blob: 905e8e493275693a77be403436bd4e0f7ee440bb [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdlib.h>
6#include <string.h>
7
8#include "src/wasm/encoder.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +01009#include "src/wasm/wasm-js.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/wasm/wasm-macro-gen.h"
11#include "src/wasm/wasm-module.h"
12#include "src/wasm/wasm-opcodes.h"
13
14#include "test/cctest/cctest.h"
15
16using namespace v8::base;
17using namespace v8::internal;
18using namespace v8::internal::compiler;
19using namespace v8::internal::wasm;
20
21
Ben Murdoch097c5b22016-05-18 11:27:45 +010022#if !V8_TARGET_ARCH_ARM64
23// TODO(titzer): fix arm64 frame alignment.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024namespace {
25void TestModule(WasmModuleIndex* module, int32_t expected_result) {
26 Isolate* isolate = CcTest::InitIsolateOnce();
Ben Murdoch097c5b22016-05-18 11:27:45 +010027 HandleScope scope(isolate);
28 WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 int32_t result =
30 CompileAndRunWasmModule(isolate, module->Begin(), module->End());
31 CHECK_EQ(expected_result, result);
32}
33} // namespace
34
35
36// A raw test that skips the WasmModuleBuilder.
37TEST(Run_WasmModule_CallAdd_rev) {
38 static const byte data[] = {
39 // sig#0 ------------------------------------------
40 kDeclSignatures, 2, 0, kLocalI32, // void -> int
41 2, kLocalI32, kLocalI32, kLocalI32, // int,int -> int
42 // func#0 (main) ----------------------------------
43 kDeclFunctions, 2, kDeclFunctionExport, 0, 0, // sig index
44 6, 0, // body size
45 kExprCallFunction, 1, // --
46 kExprI8Const, 77, // --
47 kExprI8Const, 22, // --
48 // func#1 -----------------------------------------
49 0, // no name, not exported
50 1, 0, // sig index
51 5, 0, // body size
52 kExprI32Add, // --
53 kExprGetLocal, 0, // --
54 kExprGetLocal, 1, // --
55 };
56
57 Isolate* isolate = CcTest::InitIsolateOnce();
Ben Murdoch097c5b22016-05-18 11:27:45 +010058 HandleScope scope(isolate);
59 WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 int32_t result =
61 CompileAndRunWasmModule(isolate, data, data + arraysize(data));
62 CHECK_EQ(99, result);
63}
64
65
66TEST(Run_WasmModule_Return114) {
67 static const int32_t kReturnValue = 114;
68 Zone zone;
69 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
70 uint16_t f_index = builder->AddFunction();
71 WasmFunctionBuilder* f = builder->FunctionAt(f_index);
72 f->ReturnType(kAstI32);
73 f->Exported(1);
74 byte code[] = {WASM_I8(kReturnValue)};
75 f->EmitCode(code, sizeof(code));
76 WasmModuleWriter* writer = builder->Build(&zone);
77 TestModule(writer->WriteTo(&zone), kReturnValue);
78}
79
80
81TEST(Run_WasmModule_CallAdd) {
82 Zone zone;
83 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
84 uint16_t f1_index = builder->AddFunction();
85 WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
86 f->ReturnType(kAstI32);
87 uint16_t param1 = f->AddParam(kAstI32);
88 uint16_t param2 = f->AddParam(kAstI32);
89 byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
90 uint32_t local_indices1[] = {2, 4};
91 f->EmitCode(code1, sizeof(code1), local_indices1, sizeof(local_indices1) / 4);
92 uint16_t f2_index = builder->AddFunction();
93 f = builder->FunctionAt(f2_index);
94 f->ReturnType(kAstI32);
95 f->Exported(1);
96 byte code2[] = {WASM_CALL_FUNCTION(f1_index, WASM_I8(77), WASM_I8(22))};
97 f->EmitCode(code2, sizeof(code2));
98 WasmModuleWriter* writer = builder->Build(&zone);
99 TestModule(writer->WriteTo(&zone), 99);
100}
101
102
103TEST(Run_WasmModule_ReadLoadedDataSegment) {
104 static const byte kDataSegmentDest0 = 12;
105 Zone zone;
106 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
107 uint16_t f_index = builder->AddFunction();
108 WasmFunctionBuilder* f = builder->FunctionAt(f_index);
109 f->ReturnType(kAstI32);
110 f->Exported(1);
111 byte code[] = {
112 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
113 f->EmitCode(code, sizeof(code));
114 byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
115 builder->AddDataSegment(new (&zone) WasmDataSegmentEncoder(
116 &zone, data, sizeof(data), kDataSegmentDest0));
117 WasmModuleWriter* writer = builder->Build(&zone);
118 TestModule(writer->WriteTo(&zone), 0xddccbbaa);
119}
120
121
122#if defined(__has_feature)
123#if __has_feature(address_sanitizer)
124#define V8_WITH_ASAN 1
125#endif
126#endif
127
128
129#if !defined(V8_WITH_ASAN)
130// TODO(bradnelson): Figure out why this crashes under asan.
131TEST(Run_WasmModule_CheckMemoryIsZero) {
132 static const int kCheckSize = 16 * 1024;
133 Zone zone;
134 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
135 uint16_t f_index = builder->AddFunction();
136 WasmFunctionBuilder* f = builder->FunctionAt(f_index);
137 f->ReturnType(kAstI32);
138 uint16_t localIndex = f->AddLocal(kAstI32);
139 f->Exported(1);
140 byte code[] = {WASM_BLOCK(
141 2,
142 WASM_WHILE(
143 WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32(kCheckSize)),
144 WASM_IF_ELSE(
145 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
146 WASM_BRV(2, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
147 WASM_I8(11))};
148 uint32_t local_indices[] = {7, 19, 25, 28};
149 f->EmitCode(code, sizeof(code), local_indices, sizeof(local_indices) / 4);
150 WasmModuleWriter* writer = builder->Build(&zone);
151 TestModule(writer->WriteTo(&zone), 11);
152}
153#endif
154
155
156#if !defined(V8_WITH_ASAN)
157// TODO(bradnelson): Figure out why this crashes under asan.
158TEST(Run_WasmModule_CallMain_recursive) {
159 Zone zone;
160 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
161 uint16_t f_index = builder->AddFunction();
162 WasmFunctionBuilder* f = builder->FunctionAt(f_index);
163 f->ReturnType(kAstI32);
164 uint16_t localIndex = f->AddLocal(kAstI32);
165 f->Exported(1);
166 byte code[] = {WASM_BLOCK(
167 2, WASM_SET_LOCAL(localIndex,
168 WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
169 WASM_IF_ELSE(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
170 WASM_BLOCK(2, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
171 WASM_INC_LOCAL(localIndex)),
172 WASM_BRV(1, WASM_CALL_FUNCTION0(0))),
173 WASM_BRV(0, WASM_I8(55))))};
174 uint32_t local_indices[] = {3, 11, 21, 24};
175 f->EmitCode(code, sizeof(code), local_indices, sizeof(local_indices) / 4);
176 WasmModuleWriter* writer = builder->Build(&zone);
177 TestModule(writer->WriteTo(&zone), 55);
178}
179#endif
180
181
182#if !defined(V8_WITH_ASAN)
183// TODO(bradnelson): Figure out why this crashes under asan.
184TEST(Run_WasmModule_Global) {
185 Zone zone;
186 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
187 uint32_t global1 = builder->AddGlobal(MachineType::Int32(), 0);
188 uint32_t global2 = builder->AddGlobal(MachineType::Int32(), 0);
189 uint16_t f1_index = builder->AddFunction();
190 WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
191 f->ReturnType(kAstI32);
192 byte code1[] = {
193 WASM_I32_ADD(WASM_LOAD_GLOBAL(global1), WASM_LOAD_GLOBAL(global2))};
194 f->EmitCode(code1, sizeof(code1));
195 uint16_t f2_index = builder->AddFunction();
196 f = builder->FunctionAt(f2_index);
197 f->ReturnType(kAstI32);
198 f->Exported(1);
199 byte code2[] = {WASM_STORE_GLOBAL(global1, WASM_I32(56)),
200 WASM_STORE_GLOBAL(global2, WASM_I32(41)),
201 WASM_RETURN(WASM_CALL_FUNCTION0(f1_index))};
202 f->EmitCode(code2, sizeof(code2));
203 WasmModuleWriter* writer = builder->Build(&zone);
204 TestModule(writer->WriteTo(&zone), 97);
205}
206#endif
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207
208#endif // !V8_TARGET_ARCH_ARM64