2015-12-11 12:26:16 +00:00
|
|
|
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "src/wasm/encoder.h"
|
2016-01-18 15:39:05 +00:00
|
|
|
#include "src/wasm/wasm-js.h"
|
2015-12-11 12:26:16 +00:00
|
|
|
#include "src/wasm/wasm-macro-gen.h"
|
|
|
|
#include "src/wasm/wasm-module.h"
|
|
|
|
#include "src/wasm/wasm-opcodes.h"
|
|
|
|
|
|
|
|
#include "test/cctest/cctest.h"
|
2016-05-17 17:53:46 +00:00
|
|
|
#include "test/cctest/wasm/test-signatures.h"
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
using namespace v8::base;
|
|
|
|
using namespace v8::internal;
|
|
|
|
using namespace v8::internal::compiler;
|
|
|
|
using namespace v8::internal::wasm;
|
|
|
|
|
|
|
|
namespace {
|
2016-05-25 16:12:09 +00:00
|
|
|
void TestModule(Zone* zone, WasmModuleBuilder* builder,
|
|
|
|
int32_t expected_result) {
|
|
|
|
ZoneBuffer buffer(zone);
|
2016-05-27 12:15:23 +00:00
|
|
|
builder->WriteTo(buffer);
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
2016-01-18 15:39:05 +00:00
|
|
|
HandleScope scope(isolate);
|
|
|
|
WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context());
|
2015-12-11 12:26:16 +00:00
|
|
|
int32_t result =
|
2016-05-25 16:12:09 +00:00
|
|
|
CompileAndRunWasmModule(isolate, buffer.begin(), buffer.end());
|
2015-12-11 12:26:16 +00:00
|
|
|
CHECK_EQ(expected_result, result);
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_Return114) {
|
|
|
|
static const int32_t kReturnValue = 114;
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
|
uint16_t f_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code[] = {WASM_I8(kReturnValue)};
|
|
|
|
f->EmitCode(code, sizeof(code));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, kReturnValue);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_CallAdd) {
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
2016-05-17 17:53:46 +00:00
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
uint16_t f1_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_ii());
|
|
|
|
uint16_t param1 = 0;
|
|
|
|
uint16_t param2 = 1;
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
|
2016-04-29 09:15:26 +00:00
|
|
|
f->EmitCode(code1, sizeof(code1));
|
2016-05-17 17:53:46 +00:00
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
uint16_t f2_index = builder->AddFunction();
|
|
|
|
f = builder->FunctionAt(f2_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
|
|
|
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2016-04-29 09:15:26 +00:00
|
|
|
byte code2[] = {WASM_CALL_FUNCTION2(f1_index, WASM_I8(77), WASM_I8(22))};
|
2015-12-11 12:26:16 +00:00
|
|
|
f->EmitCode(code2, sizeof(code2));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, 99);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_ReadLoadedDataSegment) {
|
|
|
|
static const byte kDataSegmentDest0 = 12;
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
|
uint16_t f_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
|
|
|
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code[] = {
|
|
|
|
WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
|
|
|
|
f->EmitCode(code, sizeof(code));
|
|
|
|
byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
|
|
|
|
builder->AddDataSegment(new (&zone) WasmDataSegmentEncoder(
|
|
|
|
&zone, data, sizeof(data), kDataSegmentDest0));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, 0xddccbbaa);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_CheckMemoryIsZero) {
|
|
|
|
static const int kCheckSize = 16 * 1024;
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
|
uint16_t f_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
uint16_t localIndex = f->AddLocal(kAstI32);
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code[] = {WASM_BLOCK(
|
|
|
|
2,
|
|
|
|
WASM_WHILE(
|
2016-03-04 19:05:47 +00:00
|
|
|
WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)),
|
2015-12-11 12:26:16 +00:00
|
|
|
WASM_IF_ELSE(
|
|
|
|
WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
|
|
|
|
WASM_BRV(2, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
|
|
|
|
WASM_I8(11))};
|
2016-05-17 17:53:46 +00:00
|
|
|
f->EmitCode(code, sizeof(code));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, 11);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_CallMain_recursive) {
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
|
uint16_t f_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
uint16_t localIndex = f->AddLocal(kAstI32);
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code[] = {WASM_BLOCK(
|
|
|
|
2, WASM_SET_LOCAL(localIndex,
|
|
|
|
WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
|
|
|
|
WASM_IF_ELSE(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
|
|
|
|
WASM_BLOCK(2, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
|
|
|
|
WASM_INC_LOCAL(localIndex)),
|
|
|
|
WASM_BRV(1, WASM_CALL_FUNCTION0(0))),
|
|
|
|
WASM_BRV(0, WASM_I8(55))))};
|
2016-05-17 17:53:46 +00:00
|
|
|
f->EmitCode(code, sizeof(code));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, 55);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Run_WasmModule_Global) {
|
2016-04-01 10:00:30 +00:00
|
|
|
v8::base::AccountingAllocator allocator;
|
|
|
|
Zone zone(&allocator);
|
2016-05-17 17:53:46 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
|
uint32_t global1 = builder->AddGlobal(MachineType::Int32(), 0);
|
|
|
|
uint32_t global2 = builder->AddGlobal(MachineType::Int32(), 0);
|
|
|
|
uint16_t f1_index = builder->AddFunction();
|
|
|
|
WasmFunctionBuilder* f = builder->FunctionAt(f1_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
2015-12-11 12:26:16 +00:00
|
|
|
byte code1[] = {
|
|
|
|
WASM_I32_ADD(WASM_LOAD_GLOBAL(global1), WASM_LOAD_GLOBAL(global2))};
|
|
|
|
f->EmitCode(code1, sizeof(code1));
|
|
|
|
uint16_t f2_index = builder->AddFunction();
|
|
|
|
f = builder->FunctionAt(f2_index);
|
2016-05-17 17:53:46 +00:00
|
|
|
f->SetSignature(sigs.i_v());
|
2016-05-27 12:15:23 +00:00
|
|
|
f->SetExported();
|
2016-03-04 19:05:47 +00:00
|
|
|
byte code2[] = {WASM_STORE_GLOBAL(global1, WASM_I32V_1(56)),
|
|
|
|
WASM_STORE_GLOBAL(global2, WASM_I32V_1(41)),
|
2016-04-29 09:15:26 +00:00
|
|
|
WASM_RETURN1(WASM_CALL_FUNCTION0(f1_index))};
|
2015-12-11 12:26:16 +00:00
|
|
|
f->EmitCode(code2, sizeof(code2));
|
2016-05-25 16:12:09 +00:00
|
|
|
TestModule(&zone, builder, 97);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|