• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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"
9 #include "src/wasm/wasm-js.h"
10 #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 #include "test/cctest/wasm/test-signatures.h"
16 
17 using namespace v8::base;
18 using namespace v8::internal;
19 using namespace v8::internal::compiler;
20 using namespace v8::internal::wasm;
21 
22 namespace {
TestModule(Zone * zone,WasmModuleBuilder * builder,int32_t expected_result)23 void TestModule(Zone* zone, WasmModuleBuilder* builder,
24                 int32_t expected_result) {
25   ZoneBuffer buffer(zone);
26   builder->WriteTo(buffer);
27 
28   Isolate* isolate = CcTest::InitIsolateOnce();
29   HandleScope scope(isolate);
30   WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context());
31   int32_t result =
32       testing::CompileAndRunWasmModule(isolate, buffer.begin(), buffer.end());
33   CHECK_EQ(expected_result, result);
34 }
35 
ExportAsMain(WasmFunctionBuilder * f)36 void ExportAsMain(WasmFunctionBuilder* f) {
37   static const char kMainName[] = "main";
38   f->SetExported();
39   f->SetName(kMainName, arraysize(kMainName) - 1);
40 }
41 }  // namespace
42 
TEST(Run_WasmModule_Return114)43 TEST(Run_WasmModule_Return114) {
44   static const int32_t kReturnValue = 114;
45   TestSignatures sigs;
46   v8::base::AccountingAllocator allocator;
47   Zone zone(&allocator);
48 
49   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
50   uint16_t f_index = builder->AddFunction();
51   WasmFunctionBuilder* f = builder->FunctionAt(f_index);
52   f->SetSignature(sigs.i_v());
53   ExportAsMain(f);
54   byte code[] = {WASM_I8(kReturnValue)};
55   f->EmitCode(code, sizeof(code));
56   TestModule(&zone, builder, kReturnValue);
57 }
58 
TEST(Run_WasmModule_CallAdd)59 TEST(Run_WasmModule_CallAdd) {
60   v8::base::AccountingAllocator allocator;
61   Zone zone(&allocator);
62   TestSignatures sigs;
63 
64   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
65 
66   uint16_t f1_index = builder->AddFunction();
67   WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
68   f->SetSignature(sigs.i_ii());
69   uint16_t param1 = 0;
70   uint16_t param2 = 1;
71   byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
72   f->EmitCode(code1, sizeof(code1));
73 
74   uint16_t f2_index = builder->AddFunction();
75   f = builder->FunctionAt(f2_index);
76   f->SetSignature(sigs.i_v());
77 
78   ExportAsMain(f);
79   byte code2[] = {WASM_CALL_FUNCTION2(f1_index, WASM_I8(77), WASM_I8(22))};
80   f->EmitCode(code2, sizeof(code2));
81   TestModule(&zone, builder, 99);
82 }
83 
TEST(Run_WasmModule_ReadLoadedDataSegment)84 TEST(Run_WasmModule_ReadLoadedDataSegment) {
85   static const byte kDataSegmentDest0 = 12;
86   v8::base::AccountingAllocator allocator;
87   Zone zone(&allocator);
88   TestSignatures sigs;
89 
90   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
91   uint16_t f_index = builder->AddFunction();
92   WasmFunctionBuilder* f = builder->FunctionAt(f_index);
93   f->SetSignature(sigs.i_v());
94 
95   ExportAsMain(f);
96   byte code[] = {
97       WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
98   f->EmitCode(code, sizeof(code));
99   byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
100   builder->AddDataSegment(new (&zone) WasmDataSegmentEncoder(
101       &zone, data, sizeof(data), kDataSegmentDest0));
102   TestModule(&zone, builder, 0xddccbbaa);
103 }
104 
TEST(Run_WasmModule_CheckMemoryIsZero)105 TEST(Run_WasmModule_CheckMemoryIsZero) {
106   static const int kCheckSize = 16 * 1024;
107   v8::base::AccountingAllocator allocator;
108   Zone zone(&allocator);
109   TestSignatures sigs;
110 
111   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
112   uint16_t f_index = builder->AddFunction();
113   WasmFunctionBuilder* f = builder->FunctionAt(f_index);
114   f->SetSignature(sigs.i_v());
115 
116   uint16_t localIndex = f->AddLocal(kAstI32);
117   ExportAsMain(f);
118   byte code[] = {WASM_BLOCK(
119       2,
120       WASM_WHILE(
121           WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)),
122           WASM_IF_ELSE(
123               WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
124               WASM_BRV(2, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
125       WASM_I8(11))};
126   f->EmitCode(code, sizeof(code));
127   TestModule(&zone, builder, 11);
128 }
129 
TEST(Run_WasmModule_CallMain_recursive)130 TEST(Run_WasmModule_CallMain_recursive) {
131   v8::base::AccountingAllocator allocator;
132   Zone zone(&allocator);
133   TestSignatures sigs;
134 
135   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
136   uint16_t f_index = builder->AddFunction();
137   WasmFunctionBuilder* f = builder->FunctionAt(f_index);
138   f->SetSignature(sigs.i_v());
139 
140   uint16_t localIndex = f->AddLocal(kAstI32);
141   ExportAsMain(f);
142   byte code[] = {WASM_BLOCK(
143       2, WASM_SET_LOCAL(localIndex,
144                         WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
145       WASM_IF_ELSE(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
146                    WASM_BLOCK(2, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
147                                                 WASM_INC_LOCAL(localIndex)),
148                               WASM_BRV(1, WASM_CALL_FUNCTION0(0))),
149                    WASM_BRV(0, WASM_I8(55))))};
150   f->EmitCode(code, sizeof(code));
151   TestModule(&zone, builder, 55);
152 }
153 
TEST(Run_WasmModule_Global)154 TEST(Run_WasmModule_Global) {
155   v8::base::AccountingAllocator allocator;
156   Zone zone(&allocator);
157   TestSignatures sigs;
158 
159   WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
160   uint32_t global1 = builder->AddGlobal(MachineType::Int32(), 0);
161   uint32_t global2 = builder->AddGlobal(MachineType::Int32(), 0);
162   uint16_t f1_index = builder->AddFunction();
163   WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
164   f->SetSignature(sigs.i_v());
165   byte code1[] = {
166       WASM_I32_ADD(WASM_LOAD_GLOBAL(global1), WASM_LOAD_GLOBAL(global2))};
167   f->EmitCode(code1, sizeof(code1));
168   uint16_t f2_index = builder->AddFunction();
169   f = builder->FunctionAt(f2_index);
170   f->SetSignature(sigs.i_v());
171   ExportAsMain(f);
172   byte code2[] = {WASM_STORE_GLOBAL(global1, WASM_I32V_1(56)),
173                   WASM_STORE_GLOBAL(global2, WASM_I32V_1(41)),
174                   WASM_RETURN1(WASM_CALL_FUNCTION0(f1_index))};
175   f->EmitCode(code2, sizeof(code2));
176   TestModule(&zone, builder, 97);
177 }
178