[wasm] Binary 11: WASM AST is now postorder.
[wasm] Binary 11: br_table takes a value. [wasm] Binary 11: Add implicit blocks to if arms. [wasm] Binary 11: Add arities to call, return, and breaks [wasm] Binary 11: Add experimental version. This CL changes the encoder, decoder, and tests to use a postorder encoding of the AST, which is more efficient in decode time and space. R=bradnelson@chromium.org,rossberg@chromium.org,binji@chromium.org BUG=chromium:575167 LOG=Y Review-Url: https://codereview.chromium.org/1830663002 Cr-Commit-Position: refs/heads/master@{#35896}
This commit is contained in:
parent
7595dfd949
commit
2aa4656eeb
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -89,66 +89,81 @@ struct GlobalIndexOperand {
|
||||
}
|
||||
};
|
||||
|
||||
struct Block;
|
||||
struct Control;
|
||||
struct BreakDepthOperand {
|
||||
uint32_t arity;
|
||||
uint32_t depth;
|
||||
Block* target;
|
||||
Control* target;
|
||||
int length;
|
||||
inline BreakDepthOperand(Decoder* decoder, const byte* pc) {
|
||||
depth = decoder->checked_read_u32v(pc, 1, &length, "break depth");
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
|
||||
depth = decoder->checked_read_u32v(pc, 1 + len1, &len2, "break depth");
|
||||
length = len1 + len2;
|
||||
target = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct BlockCountOperand {
|
||||
uint32_t count;
|
||||
int length;
|
||||
inline BlockCountOperand(Decoder* decoder, const byte* pc) {
|
||||
count = decoder->checked_read_u32v(pc, 1, &length, "block count");
|
||||
}
|
||||
};
|
||||
|
||||
struct SignatureIndexOperand {
|
||||
struct CallIndirectOperand {
|
||||
uint32_t arity;
|
||||
uint32_t index;
|
||||
FunctionSig* sig;
|
||||
int length;
|
||||
inline SignatureIndexOperand(Decoder* decoder, const byte* pc) {
|
||||
index = decoder->checked_read_u32v(pc, 1, &length, "signature index");
|
||||
inline CallIndirectOperand(Decoder* decoder, const byte* pc) {
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
|
||||
index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "signature index");
|
||||
length = len1 + len2;
|
||||
sig = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct FunctionIndexOperand {
|
||||
struct CallFunctionOperand {
|
||||
uint32_t arity;
|
||||
uint32_t index;
|
||||
FunctionSig* sig;
|
||||
int length;
|
||||
inline FunctionIndexOperand(Decoder* decoder, const byte* pc) {
|
||||
index = decoder->checked_read_u32v(pc, 1, &length, "function index");
|
||||
inline CallFunctionOperand(Decoder* decoder, const byte* pc) {
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
|
||||
index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "function index");
|
||||
length = len1 + len2;
|
||||
sig = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct ImportIndexOperand {
|
||||
struct CallImportOperand {
|
||||
uint32_t arity;
|
||||
uint32_t index;
|
||||
FunctionSig* sig;
|
||||
int length;
|
||||
inline ImportIndexOperand(Decoder* decoder, const byte* pc) {
|
||||
index = decoder->checked_read_u32v(pc, 1, &length, "import index");
|
||||
inline CallImportOperand(Decoder* decoder, const byte* pc) {
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
|
||||
index = decoder->checked_read_u32v(pc, 1 + len1, &len2, "import index");
|
||||
length = len1 + len2;
|
||||
sig = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct BranchTableOperand {
|
||||
uint32_t arity;
|
||||
uint32_t table_count;
|
||||
const byte* table;
|
||||
int length;
|
||||
inline BranchTableOperand(Decoder* decoder, const byte* pc) {
|
||||
int varint_length;
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
arity = decoder->checked_read_u32v(pc, 1, &len1, "argument count");
|
||||
table_count =
|
||||
decoder->checked_read_u32v(pc, 1, &varint_length, "expected #entries");
|
||||
length = varint_length + (table_count + 1) * sizeof(uint32_t);
|
||||
decoder->checked_read_u32v(pc, 1 + len1, &len2, "table count");
|
||||
length = len1 + len2 + (table_count + 1) * sizeof(uint32_t);
|
||||
|
||||
uint32_t table_start = 1 + varint_length;
|
||||
uint32_t table_start = 1 + len1 + len2;
|
||||
if (decoder->check(pc, table_start, (table_count + 1) * sizeof(uint32_t),
|
||||
"expected <table entries>")) {
|
||||
table = pc + table_start;
|
||||
@ -177,6 +192,15 @@ struct MemoryAccessOperand {
|
||||
}
|
||||
};
|
||||
|
||||
struct ReturnArityOperand {
|
||||
uint32_t arity;
|
||||
int length;
|
||||
|
||||
inline ReturnArityOperand(Decoder* decoder, const byte* pc) {
|
||||
arity = decoder->checked_read_u32v(pc, 1, &length, "return count");
|
||||
}
|
||||
};
|
||||
|
||||
typedef compiler::WasmGraphBuilder TFBuilder;
|
||||
struct ModuleEnv; // forward declaration of module interface.
|
||||
|
||||
|
@ -189,6 +189,16 @@ void WasmFunctionBuilder::EmitWithVarInt(WasmOpcode opcode,
|
||||
EmitVarInt(immediate);
|
||||
}
|
||||
|
||||
void WasmFunctionBuilder::EmitI32Const(int32_t value) {
|
||||
// TODO(titzer): variable-length signed and unsigned i32 constants.
|
||||
if (-128 <= value && value <= 127) {
|
||||
EmitWithU8(kExprI8Const, static_cast<byte>(value));
|
||||
} else {
|
||||
byte code[] = {WASM_I32V_5(value)};
|
||||
EmitCode(code, sizeof(code));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t WasmFunctionBuilder::EmitEditableVarIntImmediate() {
|
||||
// Guess that the immediate will be 1 byte. If it is more, we'll have to
|
||||
// shift everything down.
|
||||
|
@ -57,6 +57,7 @@ class WasmFunctionBuilder : public ZoneObject {
|
||||
void Emit(WasmOpcode opcode);
|
||||
void EmitGetLocal(uint32_t index);
|
||||
void EmitSetLocal(uint32_t index);
|
||||
void EmitI32Const(int32_t val);
|
||||
void EmitWithU8(WasmOpcode opcode, const byte immediate);
|
||||
void EmitWithU8U8(WasmOpcode opcode, const byte imm1, const byte imm2);
|
||||
void EmitWithVarInt(WasmOpcode opcode, uint32_t immediate);
|
||||
|
@ -572,11 +572,10 @@ class ModuleDecoder : public Decoder {
|
||||
// Verifies the body (code) of a given function.
|
||||
void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv,
|
||||
WasmFunction* function) {
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) {
|
||||
OFStream os(stdout);
|
||||
os << "Verifying WASM function " << WasmFunctionName(function, menv)
|
||||
<< std::endl;
|
||||
os << std::endl;
|
||||
}
|
||||
FunctionBody body = {menv, function->sig, start_,
|
||||
start_ + function->code_start_offset,
|
||||
|
@ -294,6 +294,15 @@ void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) {
|
||||
InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule);
|
||||
InstallFunc(isolate, wasm_object, "instantiateModuleFromAsm",
|
||||
InstantiateModuleFromAsm);
|
||||
|
||||
{
|
||||
// Add the Wasm.experimentalVersion property.
|
||||
Handle<String> name = v8_str(isolate, "experimentalVersion");
|
||||
PropertyAttributes attributes =
|
||||
static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
|
||||
Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate);
|
||||
JSObject::AddProperty(wasm_object, name, value, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,27 +58,41 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_NOP kExprNop
|
||||
|
||||
#define WASM_BLOCK(count, ...) kExprBlock, static_cast<byte>(count), __VA_ARGS__
|
||||
#define WASM_INFINITE_LOOP kExprLoop, 1, kExprBr, 0, kExprNop
|
||||
#define WASM_LOOP(count, ...) kExprLoop, static_cast<byte>(count), __VA_ARGS__
|
||||
#define WASM_IF(cond, tstmt) kExprIf, cond, tstmt
|
||||
#define WASM_IF_ELSE(cond, tstmt, fstmt) kExprIfElse, cond, tstmt, fstmt
|
||||
#define WASM_SELECT(cond, tval, fval) kExprSelect, cond, tval, fval
|
||||
#define WASM_BR(depth) kExprBr, static_cast<byte>(depth), kExprNop
|
||||
#define ARITY_0 0
|
||||
#define ARITY_1 1
|
||||
#define DEPTH_0 0
|
||||
#define DEPTH_1 1
|
||||
|
||||
#define WASM_BLOCK(count, ...) kExprBlock, __VA_ARGS__, kExprEnd
|
||||
#define WASM_INFINITE_LOOP \
|
||||
kExprLoop, kExprNop, kExprBr, ARITY_0, DEPTH_0, kExprEnd
|
||||
#define WASM_LOOP(count, ...) kExprLoop, __VA_ARGS__, kExprEnd
|
||||
#define WASM_IF(cond, tstmt) cond, kExprIf, tstmt, kExprEnd
|
||||
#define WASM_IF_ELSE(cond, tstmt, fstmt) \
|
||||
cond, kExprIf, tstmt, kExprElse, fstmt, kExprEnd
|
||||
#define WASM_SELECT(tval, fval, cond) tval, fval, cond, kExprSelect
|
||||
#define WASM_BR(depth) kExprNop, kExprBr, ARITY_0, static_cast<byte>(depth)
|
||||
#define WASM_BR_IF(depth, cond) \
|
||||
kExprBrIf, static_cast<byte>(depth), kExprNop, cond
|
||||
#define WASM_BRV(depth, val) kExprBr, static_cast<byte>(depth), val
|
||||
cond, kExprBrIf, ARITY_0, static_cast<byte>(depth)
|
||||
#define WASM_BRV(depth, val) val, kExprBr, ARITY_1, static_cast<byte>(depth)
|
||||
#define WASM_BRV_IF(depth, val, cond) \
|
||||
kExprBrIf, static_cast<byte>(depth), val, cond
|
||||
#define WASM_BREAK(depth) kExprBr, static_cast<byte>(depth + 1), kExprNop
|
||||
#define WASM_CONTINUE(depth) kExprBr, static_cast<byte>(depth), kExprNop
|
||||
#define WASM_BREAKV(depth, val) kExprBr, static_cast<byte>(depth + 1), val
|
||||
#define WASM_RETURN0 kExprReturn
|
||||
#define WASM_RETURN(...) kExprReturn, __VA_ARGS__
|
||||
val, cond, kExprBrIf, ARITY_1, static_cast<byte>(depth)
|
||||
#define WASM_BREAK(depth) \
|
||||
kExprNop, kExprBr, ARITY_0, static_cast<byte>(depth + 1)
|
||||
#define WASM_CONTINUE(depth) \
|
||||
kExprNop, kExprBr, ARITY_0, static_cast<byte>(depth)
|
||||
#define WASM_BREAKV(depth, val) \
|
||||
val, kExprBr, ARITY_1, static_cast<byte>(depth + 1)
|
||||
#define WASM_RETURN0 kExprReturn, ARITY_0
|
||||
#define WASM_RETURN1(val) val, kExprReturn, ARITY_1
|
||||
#define WASM_RETURNN(count, ...) __VA_ARGS__, kExprReturn, count
|
||||
#define WASM_UNREACHABLE kExprUnreachable
|
||||
|
||||
#define WASM_BR_TABLE(key, count, ...) \
|
||||
kExprBrTable, U32V_1(count), __VA_ARGS__, key
|
||||
key, kExprBrTable, ARITY_0, U32V_1(count), __VA_ARGS__
|
||||
|
||||
#define WASM_BR_TABLEV(val, key, count, ...) \
|
||||
val, key, kExprBrTable, ARITY_1, U32V_1(count), __VA_ARGS__
|
||||
|
||||
#define WASM_CASE(x) static_cast<byte>(x), static_cast<byte>(x >> 8)
|
||||
#define WASM_CASE_BR(x) static_cast<byte>(x), static_cast<byte>(0x80 | (x) >> 8)
|
||||
@ -322,193 +336,232 @@ class LocalDeclEncoder {
|
||||
static_cast<byte>(bit_cast<uint64_t>(val) >> 48), \
|
||||
static_cast<byte>(bit_cast<uint64_t>(val) >> 56)
|
||||
#define WASM_GET_LOCAL(index) kExprGetLocal, static_cast<byte>(index)
|
||||
#define WASM_SET_LOCAL(index, val) kExprSetLocal, static_cast<byte>(index), val
|
||||
#define WASM_SET_LOCAL(index, val) val, kExprSetLocal, static_cast<byte>(index)
|
||||
#define WASM_LOAD_GLOBAL(index) kExprLoadGlobal, static_cast<byte>(index)
|
||||
#define WASM_STORE_GLOBAL(index, val) \
|
||||
kExprStoreGlobal, static_cast<byte>(index), val
|
||||
#define WASM_LOAD_MEM(type, index) \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, false)), \
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET, index
|
||||
#define WASM_STORE_MEM(type, index, val) \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, true)), \
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET, index, val
|
||||
#define WASM_LOAD_MEM_OFFSET(type, offset, index) \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, false)), \
|
||||
ZERO_ALIGNMENT, U32V_1(offset), index
|
||||
#define WASM_STORE_MEM_OFFSET(type, offset, index, val) \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, true)), \
|
||||
ZERO_ALIGNMENT, U32V_1(offset), index, val
|
||||
#define WASM_CALL_FUNCTION(index, ...) \
|
||||
kExprCallFunction, static_cast<byte>(index), __VA_ARGS__
|
||||
#define WASM_CALL_IMPORT(index, ...) \
|
||||
kExprCallImport, static_cast<byte>(index), __VA_ARGS__
|
||||
#define WASM_CALL_INDIRECT(index, func, ...) \
|
||||
kExprCallIndirect, static_cast<byte>(index), func, __VA_ARGS__
|
||||
#define WASM_CALL_FUNCTION0(index) kExprCallFunction, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT0(index) kExprCallImport, static_cast<byte>(index)
|
||||
val, kExprStoreGlobal, static_cast<byte>(index)
|
||||
#define WASM_LOAD_MEM(type, index) \
|
||||
index, static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, false)), \
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET
|
||||
#define WASM_STORE_MEM(type, index, val) \
|
||||
index, val, \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, true)), \
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET
|
||||
#define WASM_LOAD_MEM_OFFSET(type, offset, index) \
|
||||
index, static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, false)), \
|
||||
ZERO_ALIGNMENT, static_cast<byte>(offset)
|
||||
#define WASM_STORE_MEM_OFFSET(type, offset, index, val) \
|
||||
index, val, \
|
||||
static_cast<byte>( \
|
||||
v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(type, true)), \
|
||||
ZERO_ALIGNMENT, static_cast<byte>(offset)
|
||||
|
||||
#define WASM_CALL_FUNCTION0(index) \
|
||||
kExprCallFunction, 0, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTION1(index, a) \
|
||||
a, kExprCallFunction, 1, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTION2(index, a, b) \
|
||||
a, b, kExprCallFunction, 2, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTION3(index, a, b, c) \
|
||||
a, b, c, kExprCallFunction, 3, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTION4(index, a, b, c, d) \
|
||||
a, b, c, d, kExprCallFunction, 4, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTION5(index, a, b, c, d, e) \
|
||||
kExprCallFunction, 5, static_cast<byte>(index)
|
||||
#define WASM_CALL_FUNCTIONN(arity, index, ...) \
|
||||
__VA_ARGS__, kExprCallFunction, arity, static_cast<byte>(index)
|
||||
|
||||
#define WASM_CALL_IMPORT0(index) kExprCallImport, 0, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT1(index, a) \
|
||||
a, kExprCallImport, 1, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT2(index, a, b) \
|
||||
a, b, kExprCallImport, 2, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT3(index, a, b, c) \
|
||||
a, b, c, kExprCallImport, 3, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT4(index, a, b, c, d) \
|
||||
a, b, c, d, kExprCallImport, 4, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORT5(index, a, b, c, d, e) \
|
||||
a, b, c, d, e, kExprCallImport, 5, static_cast<byte>(index)
|
||||
#define WASM_CALL_IMPORTN(arity, index, ...) \
|
||||
__VA_ARGS__, kExprCallImport, U32V_1(arity), static_cast<byte>(index),
|
||||
|
||||
#define WASM_CALL_INDIRECT0(index, func) \
|
||||
kExprCallIndirect, static_cast<byte>(index), func
|
||||
#define WASM_NOT(x) kExprI32Eqz, x
|
||||
func, kExprCallIndirect, 0, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECT1(index, func, a) \
|
||||
func, a, kExprCallIndirect, 1, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECT2(index, func, a, b) \
|
||||
func, a, b, kExprCallIndirect, 2, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECT3(index, func, a, b, c) \
|
||||
func, a, b, c, kExprCallIndirect, 3, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECT4(index, func, a, b, c, d) \
|
||||
func, a, b, c, d, kExprCallIndirect, 4, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECT5(index, func, a, b, c, d, e) \
|
||||
func, a, b, c, d, e, kExprCallIndirect, 5, static_cast<byte>(index)
|
||||
#define WASM_CALL_INDIRECTN(arity, index, func, ...) \
|
||||
func, __VA_ARGS__, kExprCallIndirect, U32V_1(arity), static_cast<byte>(index)
|
||||
|
||||
#define WASM_NOT(x) x, kExprI32Eqz
|
||||
#define WASM_SEQ(...) __VA_ARGS__
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constructs that are composed of multiple bytecodes.
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_WHILE(x, y) kExprLoop, 1, kExprIf, x, kExprBr, 0, y
|
||||
#define WASM_INC_LOCAL(index) \
|
||||
kExprSetLocal, static_cast<byte>(index), kExprI32Add, kExprGetLocal, \
|
||||
static_cast<byte>(index), kExprI8Const, 1
|
||||
#define WASM_INC_LOCAL_BY(index, count) \
|
||||
kExprSetLocal, static_cast<byte>(index), kExprI32Add, kExprGetLocal, \
|
||||
static_cast<byte>(index), kExprI8Const, static_cast<int8_t>(count)
|
||||
|
||||
#define WASM_UNOP(opcode, x) static_cast<byte>(opcode), x
|
||||
#define WASM_BINOP(opcode, x, y) static_cast<byte>(opcode), x, y
|
||||
#define WASM_WHILE(x, y) \
|
||||
kExprLoop, x, kExprIf, y, kExprBr, ARITY_1, DEPTH_1, kExprEnd, kExprEnd
|
||||
#define WASM_INC_LOCAL(index) \
|
||||
kExprGetLocal, static_cast<byte>(index), kExprI8Const, 1, kExprI32Add, \
|
||||
kExprSetLocal, static_cast<byte>(index)
|
||||
#define WASM_INC_LOCAL_BY(index, count) \
|
||||
kExprGetLocal, static_cast<byte>(index), kExprI8Const, \
|
||||
static_cast<byte>(count), kExprI32Add, kExprSetLocal, \
|
||||
static_cast<byte>(index)
|
||||
#define WASM_UNOP(opcode, x) x, static_cast<byte>(opcode)
|
||||
#define WASM_BINOP(opcode, x, y) x, y, static_cast<byte>(opcode)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Int32 operations
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_I32_ADD(x, y) kExprI32Add, x, y
|
||||
#define WASM_I32_SUB(x, y) kExprI32Sub, x, y
|
||||
#define WASM_I32_MUL(x, y) kExprI32Mul, x, y
|
||||
#define WASM_I32_DIVS(x, y) kExprI32DivS, x, y
|
||||
#define WASM_I32_DIVU(x, y) kExprI32DivU, x, y
|
||||
#define WASM_I32_REMS(x, y) kExprI32RemS, x, y
|
||||
#define WASM_I32_REMU(x, y) kExprI32RemU, x, y
|
||||
#define WASM_I32_AND(x, y) kExprI32And, x, y
|
||||
#define WASM_I32_IOR(x, y) kExprI32Ior, x, y
|
||||
#define WASM_I32_XOR(x, y) kExprI32Xor, x, y
|
||||
#define WASM_I32_SHL(x, y) kExprI32Shl, x, y
|
||||
#define WASM_I32_SHR(x, y) kExprI32ShrU, x, y
|
||||
#define WASM_I32_SAR(x, y) kExprI32ShrS, x, y
|
||||
#define WASM_I32_ROR(x, y) kExprI32Ror, x, y
|
||||
#define WASM_I32_ROL(x, y) kExprI32Rol, x, y
|
||||
#define WASM_I32_EQ(x, y) kExprI32Eq, x, y
|
||||
#define WASM_I32_NE(x, y) kExprI32Ne, x, y
|
||||
#define WASM_I32_LTS(x, y) kExprI32LtS, x, y
|
||||
#define WASM_I32_LES(x, y) kExprI32LeS, x, y
|
||||
#define WASM_I32_LTU(x, y) kExprI32LtU, x, y
|
||||
#define WASM_I32_LEU(x, y) kExprI32LeU, x, y
|
||||
#define WASM_I32_GTS(x, y) kExprI32GtS, x, y
|
||||
#define WASM_I32_GES(x, y) kExprI32GeS, x, y
|
||||
#define WASM_I32_GTU(x, y) kExprI32GtU, x, y
|
||||
#define WASM_I32_GEU(x, y) kExprI32GeU, x, y
|
||||
#define WASM_I32_CLZ(x) kExprI32Clz, x
|
||||
#define WASM_I32_CTZ(x) kExprI32Ctz, x
|
||||
#define WASM_I32_POPCNT(x) kExprI32Popcnt, x
|
||||
#define WASM_I32_EQZ(x) kExprI32Eqz, x
|
||||
#define WASM_I32_ADD(x, y) x, y, kExprI32Add
|
||||
#define WASM_I32_SUB(x, y) x, y, kExprI32Sub
|
||||
#define WASM_I32_MUL(x, y) x, y, kExprI32Mul
|
||||
#define WASM_I32_DIVS(x, y) x, y, kExprI32DivS
|
||||
#define WASM_I32_DIVU(x, y) x, y, kExprI32DivU
|
||||
#define WASM_I32_REMS(x, y) x, y, kExprI32RemS
|
||||
#define WASM_I32_REMU(x, y) x, y, kExprI32RemU
|
||||
#define WASM_I32_AND(x, y) x, y, kExprI32And
|
||||
#define WASM_I32_IOR(x, y) x, y, kExprI32Ior
|
||||
#define WASM_I32_XOR(x, y) x, y, kExprI32Xor
|
||||
#define WASM_I32_SHL(x, y) x, y, kExprI32Shl
|
||||
#define WASM_I32_SHR(x, y) x, y, kExprI32ShrU
|
||||
#define WASM_I32_SAR(x, y) x, y, kExprI32ShrS
|
||||
#define WASM_I32_ROR(x, y) x, y, kExprI32Ror
|
||||
#define WASM_I32_ROL(x, y) x, y, kExprI32Rol
|
||||
#define WASM_I32_EQ(x, y) x, y, kExprI32Eq
|
||||
#define WASM_I32_NE(x, y) x, y, kExprI32Ne
|
||||
#define WASM_I32_LTS(x, y) x, y, kExprI32LtS
|
||||
#define WASM_I32_LES(x, y) x, y, kExprI32LeS
|
||||
#define WASM_I32_LTU(x, y) x, y, kExprI32LtU
|
||||
#define WASM_I32_LEU(x, y) x, y, kExprI32LeU
|
||||
#define WASM_I32_GTS(x, y) x, y, kExprI32GtS
|
||||
#define WASM_I32_GES(x, y) x, y, kExprI32GeS
|
||||
#define WASM_I32_GTU(x, y) x, y, kExprI32GtU
|
||||
#define WASM_I32_GEU(x, y) x, y, kExprI32GeU
|
||||
#define WASM_I32_CLZ(x) x, kExprI32Clz
|
||||
#define WASM_I32_CTZ(x) x, kExprI32Ctz
|
||||
#define WASM_I32_POPCNT(x) x, kExprI32Popcnt
|
||||
#define WASM_I32_EQZ(x) x, kExprI32Eqz
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Int64 operations
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_I64_ADD(x, y) kExprI64Add, x, y
|
||||
#define WASM_I64_SUB(x, y) kExprI64Sub, x, y
|
||||
#define WASM_I64_MUL(x, y) kExprI64Mul, x, y
|
||||
#define WASM_I64_DIVS(x, y) kExprI64DivS, x, y
|
||||
#define WASM_I64_DIVU(x, y) kExprI64DivU, x, y
|
||||
#define WASM_I64_REMS(x, y) kExprI64RemS, x, y
|
||||
#define WASM_I64_REMU(x, y) kExprI64RemU, x, y
|
||||
#define WASM_I64_AND(x, y) kExprI64And, x, y
|
||||
#define WASM_I64_IOR(x, y) kExprI64Ior, x, y
|
||||
#define WASM_I64_XOR(x, y) kExprI64Xor, x, y
|
||||
#define WASM_I64_SHL(x, y) kExprI64Shl, x, y
|
||||
#define WASM_I64_SHR(x, y) kExprI64ShrU, x, y
|
||||
#define WASM_I64_SAR(x, y) kExprI64ShrS, x, y
|
||||
#define WASM_I64_ROR(x, y) kExprI64Ror, x, y
|
||||
#define WASM_I64_ROL(x, y) kExprI64Rol, x, y
|
||||
#define WASM_I64_EQ(x, y) kExprI64Eq, x, y
|
||||
#define WASM_I64_NE(x, y) kExprI64Ne, x, y
|
||||
#define WASM_I64_LTS(x, y) kExprI64LtS, x, y
|
||||
#define WASM_I64_LES(x, y) kExprI64LeS, x, y
|
||||
#define WASM_I64_LTU(x, y) kExprI64LtU, x, y
|
||||
#define WASM_I64_LEU(x, y) kExprI64LeU, x, y
|
||||
#define WASM_I64_GTS(x, y) kExprI64GtS, x, y
|
||||
#define WASM_I64_GES(x, y) kExprI64GeS, x, y
|
||||
#define WASM_I64_GTU(x, y) kExprI64GtU, x, y
|
||||
#define WASM_I64_GEU(x, y) kExprI64GeU, x, y
|
||||
#define WASM_I64_CLZ(x) kExprI64Clz, x
|
||||
#define WASM_I64_CTZ(x) kExprI64Ctz, x
|
||||
#define WASM_I64_POPCNT(x) kExprI64Popcnt, x
|
||||
#define WASM_I64_EQZ(x) kExprI64Eqz, x
|
||||
#define WASM_I64_ADD(x, y) x, y, kExprI64Add
|
||||
#define WASM_I64_SUB(x, y) x, y, kExprI64Sub
|
||||
#define WASM_I64_MUL(x, y) x, y, kExprI64Mul
|
||||
#define WASM_I64_DIVS(x, y) x, y, kExprI64DivS
|
||||
#define WASM_I64_DIVU(x, y) x, y, kExprI64DivU
|
||||
#define WASM_I64_REMS(x, y) x, y, kExprI64RemS
|
||||
#define WASM_I64_REMU(x, y) x, y, kExprI64RemU
|
||||
#define WASM_I64_AND(x, y) x, y, kExprI64And
|
||||
#define WASM_I64_IOR(x, y) x, y, kExprI64Ior
|
||||
#define WASM_I64_XOR(x, y) x, y, kExprI64Xor
|
||||
#define WASM_I64_SHL(x, y) x, y, kExprI64Shl
|
||||
#define WASM_I64_SHR(x, y) x, y, kExprI64ShrU
|
||||
#define WASM_I64_SAR(x, y) x, y, kExprI64ShrS
|
||||
#define WASM_I64_ROR(x, y) x, y, kExprI64Ror
|
||||
#define WASM_I64_ROL(x, y) x, y, kExprI64Rol
|
||||
#define WASM_I64_EQ(x, y) x, y, kExprI64Eq
|
||||
#define WASM_I64_NE(x, y) x, y, kExprI64Ne
|
||||
#define WASM_I64_LTS(x, y) x, y, kExprI64LtS
|
||||
#define WASM_I64_LES(x, y) x, y, kExprI64LeS
|
||||
#define WASM_I64_LTU(x, y) x, y, kExprI64LtU
|
||||
#define WASM_I64_LEU(x, y) x, y, kExprI64LeU
|
||||
#define WASM_I64_GTS(x, y) x, y, kExprI64GtS
|
||||
#define WASM_I64_GES(x, y) x, y, kExprI64GeS
|
||||
#define WASM_I64_GTU(x, y) x, y, kExprI64GtU
|
||||
#define WASM_I64_GEU(x, y) x, y, kExprI64GeU
|
||||
#define WASM_I64_CLZ(x) x, kExprI64Clz
|
||||
#define WASM_I64_CTZ(x) x, kExprI64Ctz
|
||||
#define WASM_I64_POPCNT(x) x, kExprI64Popcnt
|
||||
#define WASM_I64_EQZ(x) x, kExprI64Eqz
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Float32 operations
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_F32_ADD(x, y) kExprF32Add, x, y
|
||||
#define WASM_F32_SUB(x, y) kExprF32Sub, x, y
|
||||
#define WASM_F32_MUL(x, y) kExprF32Mul, x, y
|
||||
#define WASM_F32_DIV(x, y) kExprF32Div, x, y
|
||||
#define WASM_F32_MIN(x, y) kExprF32Min, x, y
|
||||
#define WASM_F32_MAX(x, y) kExprF32Max, x, y
|
||||
#define WASM_F32_ABS(x) kExprF32Abs, x
|
||||
#define WASM_F32_NEG(x) kExprF32Neg, x
|
||||
#define WASM_F32_COPYSIGN(x, y) kExprF32CopySign, x, y
|
||||
#define WASM_F32_CEIL(x) kExprF32Ceil, x
|
||||
#define WASM_F32_FLOOR(x) kExprF32Floor, x
|
||||
#define WASM_F32_TRUNC(x) kExprF32Trunc, x
|
||||
#define WASM_F32_NEARESTINT(x) kExprF32NearestInt, x
|
||||
#define WASM_F32_SQRT(x) kExprF32Sqrt, x
|
||||
#define WASM_F32_EQ(x, y) kExprF32Eq, x, y
|
||||
#define WASM_F32_NE(x, y) kExprF32Ne, x, y
|
||||
#define WASM_F32_LT(x, y) kExprF32Lt, x, y
|
||||
#define WASM_F32_LE(x, y) kExprF32Le, x, y
|
||||
#define WASM_F32_GT(x, y) kExprF32Gt, x, y
|
||||
#define WASM_F32_GE(x, y) kExprF32Ge, x, y
|
||||
#define WASM_F32_ADD(x, y) x, y, kExprF32Add
|
||||
#define WASM_F32_SUB(x, y) x, y, kExprF32Sub
|
||||
#define WASM_F32_MUL(x, y) x, y, kExprF32Mul
|
||||
#define WASM_F32_DIV(x, y) x, y, kExprF32Div
|
||||
#define WASM_F32_MIN(x, y) x, y, kExprF32Min
|
||||
#define WASM_F32_MAX(x, y) x, y, kExprF32Max
|
||||
#define WASM_F32_ABS(x) x, kExprF32Abs
|
||||
#define WASM_F32_NEG(x) x, kExprF32Neg
|
||||
#define WASM_F32_COPYSIGN(x, y) x, y, kExprF32CopySign
|
||||
#define WASM_F32_CEIL(x) x, kExprF32Ceil
|
||||
#define WASM_F32_FLOOR(x) x, kExprF32Floor
|
||||
#define WASM_F32_TRUNC(x) x, kExprF32Trunc
|
||||
#define WASM_F32_NEARESTINT(x) x, kExprF32NearestInt
|
||||
#define WASM_F32_SQRT(x) x, kExprF32Sqrt
|
||||
#define WASM_F32_EQ(x, y) x, y, kExprF32Eq
|
||||
#define WASM_F32_NE(x, y) x, y, kExprF32Ne
|
||||
#define WASM_F32_LT(x, y) x, y, kExprF32Lt
|
||||
#define WASM_F32_LE(x, y) x, y, kExprF32Le
|
||||
#define WASM_F32_GT(x, y) x, y, kExprF32Gt
|
||||
#define WASM_F32_GE(x, y) x, y, kExprF32Ge
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Float64 operations
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_F64_ADD(x, y) kExprF64Add, x, y
|
||||
#define WASM_F64_SUB(x, y) kExprF64Sub, x, y
|
||||
#define WASM_F64_MUL(x, y) kExprF64Mul, x, y
|
||||
#define WASM_F64_DIV(x, y) kExprF64Div, x, y
|
||||
#define WASM_F64_MIN(x, y) kExprF64Min, x, y
|
||||
#define WASM_F64_MAX(x, y) kExprF64Max, x, y
|
||||
#define WASM_F64_ABS(x) kExprF64Abs, x
|
||||
#define WASM_F64_NEG(x) kExprF64Neg, x
|
||||
#define WASM_F64_COPYSIGN(x, y) kExprF64CopySign, x, y
|
||||
#define WASM_F64_CEIL(x) kExprF64Ceil, x
|
||||
#define WASM_F64_FLOOR(x) kExprF64Floor, x
|
||||
#define WASM_F64_TRUNC(x) kExprF64Trunc, x
|
||||
#define WASM_F64_NEARESTINT(x) kExprF64NearestInt, x
|
||||
#define WASM_F64_SQRT(x) kExprF64Sqrt, x
|
||||
#define WASM_F64_EQ(x, y) kExprF64Eq, x, y
|
||||
#define WASM_F64_NE(x, y) kExprF64Ne, x, y
|
||||
#define WASM_F64_LT(x, y) kExprF64Lt, x, y
|
||||
#define WASM_F64_LE(x, y) kExprF64Le, x, y
|
||||
#define WASM_F64_GT(x, y) kExprF64Gt, x, y
|
||||
#define WASM_F64_GE(x, y) kExprF64Ge, x, y
|
||||
#define WASM_F64_ADD(x, y) x, y, kExprF64Add
|
||||
#define WASM_F64_SUB(x, y) x, y, kExprF64Sub
|
||||
#define WASM_F64_MUL(x, y) x, y, kExprF64Mul
|
||||
#define WASM_F64_DIV(x, y) x, y, kExprF64Div
|
||||
#define WASM_F64_MIN(x, y) x, y, kExprF64Min
|
||||
#define WASM_F64_MAX(x, y) x, y, kExprF64Max
|
||||
#define WASM_F64_ABS(x) x, kExprF64Abs
|
||||
#define WASM_F64_NEG(x) x, kExprF64Neg
|
||||
#define WASM_F64_COPYSIGN(x, y) x, y, kExprF64CopySign
|
||||
#define WASM_F64_CEIL(x) x, kExprF64Ceil
|
||||
#define WASM_F64_FLOOR(x) x, kExprF64Floor
|
||||
#define WASM_F64_TRUNC(x) x, kExprF64Trunc
|
||||
#define WASM_F64_NEARESTINT(x) x, kExprF64NearestInt
|
||||
#define WASM_F64_SQRT(x) x, kExprF64Sqrt
|
||||
#define WASM_F64_EQ(x, y) x, y, kExprF64Eq
|
||||
#define WASM_F64_NE(x, y) x, y, kExprF64Ne
|
||||
#define WASM_F64_LT(x, y) x, y, kExprF64Lt
|
||||
#define WASM_F64_LE(x, y) x, y, kExprF64Le
|
||||
#define WASM_F64_GT(x, y) x, y, kExprF64Gt
|
||||
#define WASM_F64_GE(x, y) x, y, kExprF64Ge
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Type conversions.
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_I32_SCONVERT_F32(x) kExprI32SConvertF32, x
|
||||
#define WASM_I32_SCONVERT_F64(x) kExprI32SConvertF64, x
|
||||
#define WASM_I32_UCONVERT_F32(x) kExprI32UConvertF32, x
|
||||
#define WASM_I32_UCONVERT_F64(x) kExprI32UConvertF64, x
|
||||
#define WASM_I32_CONVERT_I64(x) kExprI32ConvertI64, x
|
||||
#define WASM_I64_SCONVERT_F32(x) kExprI64SConvertF32, x
|
||||
#define WASM_I64_SCONVERT_F64(x) kExprI64SConvertF64, x
|
||||
#define WASM_I64_UCONVERT_F32(x) kExprI64UConvertF32, x
|
||||
#define WASM_I64_UCONVERT_F64(x) kExprI64UConvertF64, x
|
||||
#define WASM_I64_SCONVERT_I32(x) kExprI64SConvertI32, x
|
||||
#define WASM_I64_UCONVERT_I32(x) kExprI64UConvertI32, x
|
||||
#define WASM_F32_SCONVERT_I32(x) kExprF32SConvertI32, x
|
||||
#define WASM_F32_UCONVERT_I32(x) kExprF32UConvertI32, x
|
||||
#define WASM_F32_SCONVERT_I64(x) kExprF32SConvertI64, x
|
||||
#define WASM_F32_UCONVERT_I64(x) kExprF32UConvertI64, x
|
||||
#define WASM_F32_CONVERT_F64(x) kExprF32ConvertF64, x
|
||||
#define WASM_F32_REINTERPRET_I32(x) kExprF32ReinterpretI32, x
|
||||
#define WASM_F64_SCONVERT_I32(x) kExprF64SConvertI32, x
|
||||
#define WASM_F64_UCONVERT_I32(x) kExprF64UConvertI32, x
|
||||
#define WASM_F64_SCONVERT_I64(x) kExprF64SConvertI64, x
|
||||
#define WASM_F64_UCONVERT_I64(x) kExprF64UConvertI64, x
|
||||
#define WASM_F64_CONVERT_F32(x) kExprF64ConvertF32, x
|
||||
#define WASM_F64_REINTERPRET_I64(x) kExprF64ReinterpretI64, x
|
||||
#define WASM_I32_REINTERPRET_F32(x) kExprI32ReinterpretF32, x
|
||||
#define WASM_I64_REINTERPRET_F64(x) kExprI64ReinterpretF64, x
|
||||
#define WASM_I32_SCONVERT_F32(x) x, kExprI32SConvertF32
|
||||
#define WASM_I32_SCONVERT_F64(x) x, kExprI32SConvertF64
|
||||
#define WASM_I32_UCONVERT_F32(x) x, kExprI32UConvertF32
|
||||
#define WASM_I32_UCONVERT_F64(x) x, kExprI32UConvertF64
|
||||
#define WASM_I32_CONVERT_I64(x) x, kExprI32ConvertI64
|
||||
#define WASM_I64_SCONVERT_F32(x) x, kExprI64SConvertF32
|
||||
#define WASM_I64_SCONVERT_F64(x) x, kExprI64SConvertF64
|
||||
#define WASM_I64_UCONVERT_F32(x) x, kExprI64UConvertF32
|
||||
#define WASM_I64_UCONVERT_F64(x) x, kExprI64UConvertF64
|
||||
#define WASM_I64_SCONVERT_I32(x) x, kExprI64SConvertI32
|
||||
#define WASM_I64_UCONVERT_I32(x) x, kExprI64UConvertI32
|
||||
#define WASM_F32_SCONVERT_I32(x) x, kExprF32SConvertI32
|
||||
#define WASM_F32_UCONVERT_I32(x) x, kExprF32UConvertI32
|
||||
#define WASM_F32_SCONVERT_I64(x) x, kExprF32SConvertI64
|
||||
#define WASM_F32_UCONVERT_I64(x) x, kExprF32UConvertI64
|
||||
#define WASM_F32_CONVERT_F64(x) x, kExprF32ConvertF64
|
||||
#define WASM_F32_REINTERPRET_I32(x) x, kExprF32ReinterpretI32
|
||||
#define WASM_F64_SCONVERT_I32(x) x, kExprF64SConvertI32
|
||||
#define WASM_F64_UCONVERT_I32(x) x, kExprF64UConvertI32
|
||||
#define WASM_F64_SCONVERT_I64(x) x, kExprF64SConvertI64
|
||||
#define WASM_F64_UCONVERT_I64(x) x, kExprF64UConvertI64
|
||||
#define WASM_F64_CONVERT_F32(x) x, kExprF64ConvertF32
|
||||
#define WASM_F64_REINTERPRET_I64(x) x, kExprF64ReinterpretI64
|
||||
#define WASM_I32_REINTERPRET_F32(x) x, kExprI32ReinterpretF32
|
||||
#define WASM_I64_REINTERPRET_F64(x) x, kExprI64ReinterpretF64
|
||||
|
||||
#endif // V8_WASM_MACRO_GEN_H_
|
||||
|
@ -25,6 +25,18 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char* WasmOpcodes::ShortOpcodeName(WasmOpcode opcode) {
|
||||
switch (opcode) {
|
||||
#define DECLARE_NAME_CASE(name, opcode, sig) \
|
||||
case kExpr##name: \
|
||||
return #name;
|
||||
FOREACH_OPCODE(DECLARE_NAME_CASE)
|
||||
#undef DECLARE_NAME_CASE
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
|
||||
if (sig.return_count() == 0) os << "v";
|
||||
|
@ -51,37 +51,35 @@ std::ostream& operator<<(std::ostream& os, const FunctionSig& function);
|
||||
|
||||
typedef Vector<const char> WasmName;
|
||||
|
||||
// TODO(titzer): Renumber all the opcodes to fill in holes.
|
||||
|
||||
// Control expressions and blocks.
|
||||
#define FOREACH_CONTROL_OPCODE(V) \
|
||||
V(Nop, 0x00, _) \
|
||||
V(Block, 0x01, _) \
|
||||
V(Loop, 0x02, _) \
|
||||
V(If, 0x03, _) \
|
||||
V(IfElse, 0x04, _) \
|
||||
V(Else, 0x04, _) \
|
||||
V(Select, 0x05, _) \
|
||||
V(Br, 0x06, _) \
|
||||
V(BrIf, 0x07, _) \
|
||||
V(BrTable, 0x08, _) \
|
||||
V(Return, 0x14, _) \
|
||||
V(Unreachable, 0x15, _)
|
||||
V(Return, 0x09, _) \
|
||||
V(Unreachable, 0x0a, _) \
|
||||
V(End, 0x0F, _)
|
||||
|
||||
// Constants, locals, globals, and calls.
|
||||
#define FOREACH_MISC_OPCODE(V) \
|
||||
V(I8Const, 0x09, _) \
|
||||
V(I32Const, 0x0a, _) \
|
||||
V(I64Const, 0x0b, _) \
|
||||
V(F64Const, 0x0c, _) \
|
||||
V(F32Const, 0x0d, _) \
|
||||
V(GetLocal, 0x0e, _) \
|
||||
V(SetLocal, 0x0f, _) \
|
||||
V(LoadGlobal, 0x10, _) \
|
||||
V(StoreGlobal, 0x11, _) \
|
||||
V(CallFunction, 0x12, _) \
|
||||
V(CallIndirect, 0x13, _) \
|
||||
V(CallImport, 0x1F, _) \
|
||||
V(DeclLocals, 0x1E, _)
|
||||
V(I32Const, 0x10, _) \
|
||||
V(I64Const, 0x11, _) \
|
||||
V(F64Const, 0x12, _) \
|
||||
V(F32Const, 0x13, _) \
|
||||
V(GetLocal, 0x14, _) \
|
||||
V(SetLocal, 0x15, _) \
|
||||
V(CallFunction, 0x16, _) \
|
||||
V(CallIndirect, 0x17, _) \
|
||||
V(CallImport, 0x18, _) \
|
||||
V(I8Const, 0xcb, _) \
|
||||
V(LoadGlobal, 0xcc, _) \
|
||||
V(StoreGlobal, 0xcd, _)
|
||||
|
||||
// Load memory expressions.
|
||||
#define FOREACH_LOAD_MEM_OPCODE(V) \
|
||||
@ -349,6 +347,7 @@ class WasmOpcodes {
|
||||
public:
|
||||
static bool IsSupported(WasmOpcode opcode);
|
||||
static const char* OpcodeName(WasmOpcode opcode);
|
||||
static const char* ShortOpcodeName(WasmOpcode opcode);
|
||||
static FunctionSig* Signature(WasmOpcode opcode);
|
||||
|
||||
static int TrapReasonToMessageId(TrapReason reason);
|
||||
|
@ -24,8 +24,8 @@
|
||||
|
||||
#define asu64(x) static_cast<uint64_t>(x)
|
||||
|
||||
#define B2(a, b) kExprBlock, 2, a, b
|
||||
#define B1(a) kExprBlock, 1, a
|
||||
#define B2(a, b) kExprBlock, a, b, kExprEnd
|
||||
#define B1(a) kExprBlock, a, kExprEnd
|
||||
|
||||
// Can't bridge macro land with nested macros.
|
||||
#if V8_TARGET_ARCH_MIPS
|
||||
@ -116,7 +116,7 @@ TEST(Run_Wasm_Return_I64) {
|
||||
REQUIRE(I64Return);
|
||||
WasmRunner<int64_t> r(MachineType::Int64());
|
||||
|
||||
BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
|
||||
BUILD(r, WASM_RETURN1(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
|
||||
}
|
||||
@ -816,8 +816,8 @@ TEST(Run_WasmCallI64Parameter) {
|
||||
WasmRunner<int32_t> r(&module);
|
||||
BUILD(
|
||||
r,
|
||||
WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION(
|
||||
index, WASM_I64V_9(0xbcd12340000000b),
|
||||
WASM_I32_CONVERT_I64(WASM_CALL_FUNCTIONN(
|
||||
19, index, WASM_I64V_9(0xbcd12340000000b),
|
||||
WASM_I64V_9(0xbcd12340000000c), WASM_I32V_1(0xd),
|
||||
WASM_I32_CONVERT_I64(WASM_I64V_9(0xbcd12340000000e)),
|
||||
WASM_I64V_9(0xbcd12340000000f), WASM_I64V_10(0xbcd1234000000010),
|
||||
@ -1093,7 +1093,7 @@ TEST(Run_WasmCall_Int64Sub) {
|
||||
|
||||
// Build the caller function.
|
||||
WasmRunner<int64_t> r(&module, MachineType::Int64(), MachineType::Int64());
|
||||
BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
|
||||
FOR_INT32_INPUTS(i) {
|
||||
FOR_INT32_INPUTS(j) {
|
||||
@ -1120,12 +1120,16 @@ TEST(Run_Wasm_LoadStoreI64_sx) {
|
||||
byte* memory = module.AddMemoryElems<byte>(16);
|
||||
WasmRunner<int64_t> r(&module);
|
||||
|
||||
byte code[] = {kExprI64StoreMem, ZERO_ALIGNMENT,
|
||||
ZERO_OFFSET, // --
|
||||
kExprI8Const, 8, // --
|
||||
loads[m], ZERO_ALIGNMENT,
|
||||
ZERO_OFFSET, // --
|
||||
kExprI8Const, 0}; // --
|
||||
byte code[] = {
|
||||
kExprI8Const, 8, // --
|
||||
kExprI8Const, 0, // --
|
||||
loads[m], // --
|
||||
ZERO_ALIGNMENT, // --
|
||||
ZERO_OFFSET, // --
|
||||
kExprI64StoreMem, // --
|
||||
ZERO_ALIGNMENT, // --
|
||||
ZERO_OFFSET // --
|
||||
};
|
||||
|
||||
r.Build(code, code + arraysize(code));
|
||||
|
||||
|
@ -156,7 +156,7 @@ TEST(Run_CallJS_Add_jswrapped) {
|
||||
WasmFunctionCompiler t(sigs.i_i(), &module);
|
||||
uint32_t js_index =
|
||||
module.AddJsFunction(sigs.i_i(), "(function(a) { return a + 99; })");
|
||||
BUILD(t, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0)));
|
||||
BUILD(t, WASM_CALL_FUNCTION1(js_index, WASM_GET_LOCAL(0)));
|
||||
|
||||
Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
|
||||
|
||||
@ -182,12 +182,14 @@ void RunJSSelectTest(int which) {
|
||||
|
||||
{
|
||||
std::vector<byte> code;
|
||||
ADD_CODE(code, kExprCallFunction, static_cast<byte>(js_index));
|
||||
|
||||
for (int i = 0; i < num_params; i++) {
|
||||
ADD_CODE(code, WASM_F64(inputs.arg_d(i)));
|
||||
}
|
||||
|
||||
ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params),
|
||||
static_cast<byte>(js_index));
|
||||
|
||||
size_t end = code.size();
|
||||
code.push_back(0);
|
||||
t.Build(&code[0], &code[end]);
|
||||
@ -370,12 +372,13 @@ void RunJSSelectAlignTest(int num_args, int num_params) {
|
||||
|
||||
// Build the calling code.
|
||||
std::vector<byte> code;
|
||||
ADD_CODE(code, kExprCallFunction, 0);
|
||||
|
||||
for (int i = 0; i < num_params; i++) {
|
||||
ADD_CODE(code, WASM_GET_LOCAL(i));
|
||||
}
|
||||
|
||||
ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params), 0);
|
||||
|
||||
size_t end = code.size();
|
||||
code.push_back(0);
|
||||
|
||||
|
@ -37,25 +37,26 @@ TEST(Run_WasmModule_CallAdd_rev) {
|
||||
static const byte data[] = {
|
||||
WASM_MODULE_HEADER,
|
||||
// sig#0 ------------------------------------------
|
||||
WASM_SECTION_SIGNATURES_SIZE + 7, // Section size.
|
||||
WASM_SECTION_SIGNATURES, 2, 0, kLocalI32, // void -> int
|
||||
2, kLocalI32, kLocalI32, kLocalI32, // int,int -> int
|
||||
WASM_SECTION_SIGNATURES_SIZE + 7, // Section size.
|
||||
WASM_SECTION_SIGNATURES, 2, // --
|
||||
0, kLocalI32, // void -> int
|
||||
2, kLocalI32, kLocalI32, kLocalI32, // int,int -> int
|
||||
// func#0 (main) ----------------------------------
|
||||
WASM_SECTION_FUNCTIONS_SIZE + 24, WASM_SECTION_FUNCTIONS, 2,
|
||||
WASM_SECTION_FUNCTIONS_SIZE + 25, WASM_SECTION_FUNCTIONS, 2,
|
||||
kDeclFunctionExport, 0, 0, // sig index
|
||||
7, 0, // body size
|
||||
8, 0, // body size
|
||||
0, // locals
|
||||
kExprCallFunction, 1, // --
|
||||
kExprI8Const, 77, // --
|
||||
kExprI8Const, 22, // --
|
||||
kExprCallFunction, 2, 1, // --
|
||||
// func#1 -----------------------------------------
|
||||
0, // no name, not exported
|
||||
1, 0, // sig index
|
||||
6, 0, // body size
|
||||
0, // locals
|
||||
kExprI32Add, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI32Add, // --
|
||||
};
|
||||
|
||||
Isolate* isolate = CcTest::InitIsolateOnce();
|
||||
@ -93,13 +94,12 @@ TEST(Run_WasmModule_CallAdd) {
|
||||
uint16_t param1 = f->AddParam(kAstI32);
|
||||
uint16_t param2 = f->AddParam(kAstI32);
|
||||
byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
|
||||
uint32_t local_indices1[] = {2, 4};
|
||||
f->EmitCode(code1, sizeof(code1), local_indices1, sizeof(local_indices1) / 4);
|
||||
f->EmitCode(code1, sizeof(code1));
|
||||
uint16_t f2_index = builder->AddFunction();
|
||||
f = builder->FunctionAt(f2_index);
|
||||
f->ReturnType(kAstI32);
|
||||
f->Exported(1);
|
||||
byte code2[] = {WASM_CALL_FUNCTION(f1_index, WASM_I8(77), WASM_I8(22))};
|
||||
byte code2[] = {WASM_CALL_FUNCTION2(f1_index, WASM_I8(77), WASM_I8(22))};
|
||||
f->EmitCode(code2, sizeof(code2));
|
||||
WasmModuleWriter* writer = builder->Build(&zone);
|
||||
TestModule(writer->WriteTo(&zone), 99);
|
||||
@ -188,7 +188,7 @@ TEST(Run_WasmModule_Global) {
|
||||
f->Exported(1);
|
||||
byte code2[] = {WASM_STORE_GLOBAL(global1, WASM_I32V_1(56)),
|
||||
WASM_STORE_GLOBAL(global2, WASM_I32V_1(41)),
|
||||
WASM_RETURN(WASM_CALL_FUNCTION0(f1_index))};
|
||||
WASM_RETURN1(WASM_CALL_FUNCTION0(f1_index))};
|
||||
f->EmitCode(code2, sizeof(code2));
|
||||
WasmModuleWriter* writer = builder->Build(&zone);
|
||||
TestModule(writer->WriteTo(&zone), 97);
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/base/platform/elapsed-timer.h"
|
||||
|
||||
#include "src/wasm/wasm-macro-gen.h"
|
||||
|
||||
#include "test/cctest/cctest.h"
|
||||
@ -19,10 +21,10 @@ using namespace v8::internal::compiler;
|
||||
using namespace v8::internal::wasm;
|
||||
|
||||
// for even shorter tests.
|
||||
#define B2(a, b) kExprBlock, 2, a, b
|
||||
#define B1(a) kExprBlock, 1, a
|
||||
#define RET(x) kExprReturn, x
|
||||
#define RET_I8(x) kExprReturn, kExprI8Const, x
|
||||
#define B2(a, b) kExprBlock, a, b, kExprEnd
|
||||
#define B1(a) kExprBlock, a, kExprEnd
|
||||
#define RET(x) x, kExprReturn, 1
|
||||
#define RET_I8(x) kExprI8Const, x, kExprReturn, 1
|
||||
|
||||
TEST(Run_WasmInt8Const) {
|
||||
WasmRunner<int32_t> r;
|
||||
@ -686,6 +688,25 @@ TEST(Run_Wasm_IfElse_P) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_If_chain) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
// if (p0) 13; if (p0) 14; 15
|
||||
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_I8(13)),
|
||||
WASM_IF(WASM_GET_LOCAL(0), WASM_I8(14)), WASM_I8(15));
|
||||
FOR_INT32_INPUTS(i) { CHECK_EQ(15, r.Call(*i)); }
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_If_chain_set) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
|
||||
// if (p0) p1 = 73; if (p0) p1 = 74; p1
|
||||
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(73))),
|
||||
WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(74))),
|
||||
WASM_GET_LOCAL(1));
|
||||
FOR_INT32_INPUTS(i) {
|
||||
int32_t expected = *i ? 74 : *i;
|
||||
CHECK_EQ(expected, r.Call(*i, *i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_IfElse_Unreachable1) {
|
||||
WasmRunner<int32_t> r;
|
||||
@ -1073,7 +1094,7 @@ TEST(Run_Wasm_Block_If_P) {
|
||||
// { if (p0) return 51; return 52; }
|
||||
BUILD(r, B2( // --
|
||||
WASM_IF(WASM_GET_LOCAL(0), // --
|
||||
WASM_BRV(0, WASM_I8(51))), // --
|
||||
WASM_BRV(1, WASM_I8(51))), // --
|
||||
WASM_I8(52))); // --
|
||||
FOR_INT32_INPUTS(i) {
|
||||
int32_t expected = *i ? 51 : 52;
|
||||
@ -1174,7 +1195,7 @@ TEST(Run_Wasm_CountDown) {
|
||||
WASM_BLOCK(
|
||||
2, WASM_LOOP(
|
||||
1, WASM_IF(WASM_GET_LOCAL(0),
|
||||
WASM_BRV(0, WASM_SET_LOCAL(
|
||||
WASM_BRV(1, WASM_SET_LOCAL(
|
||||
0, WASM_I32_SUB(WASM_GET_LOCAL(0),
|
||||
WASM_I8(1)))))),
|
||||
WASM_GET_LOCAL(0)));
|
||||
@ -1188,7 +1209,7 @@ TEST(Run_Wasm_CountDown_fallthru) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r,
|
||||
WASM_BLOCK(
|
||||
2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(0)),
|
||||
2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(1)),
|
||||
WASM_SET_LOCAL(
|
||||
0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
|
||||
WASM_CONTINUE(0)),
|
||||
@ -1214,7 +1235,7 @@ TEST(Run_Wasm_WhileCountDown) {
|
||||
|
||||
TEST(Run_Wasm_Loop_if_break1) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, B2(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(0)),
|
||||
BUILD(r, B2(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
|
||||
WASM_SET_LOCAL(0, WASM_I8(99))),
|
||||
WASM_GET_LOCAL(0)));
|
||||
CHECK_EQ(99, r.Call(0));
|
||||
@ -1247,6 +1268,23 @@ TEST(Run_Wasm_Loop_if_break_fallthru) {
|
||||
CHECK_EQ(-22, r.Call(-22));
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_IfBreak1) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), WASM_UNREACHABLE)),
|
||||
WASM_I8(91));
|
||||
CHECK_EQ(91, r.Call(0));
|
||||
CHECK_EQ(91, r.Call(1));
|
||||
CHECK_EQ(91, r.Call(-8734));
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_IfBreak2) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), RET_I8(77))),
|
||||
WASM_I8(81));
|
||||
CHECK_EQ(81, r.Call(0));
|
||||
CHECK_EQ(81, r.Call(1));
|
||||
CHECK_EQ(81, r.Call(-8734));
|
||||
}
|
||||
|
||||
TEST(Run_Wasm_LoadMemI32) {
|
||||
TestingModule module;
|
||||
@ -1528,10 +1566,10 @@ TEST(Run_Wasm_CheckMachIntsZero) {
|
||||
module.AddMemoryElems<uint32_t>(kNumElems);
|
||||
WasmRunner<uint32_t> r(&module, MachineType::Int32());
|
||||
|
||||
BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0,
|
||||
kExprIfElse, kExprI32LoadMem, ZERO_ALIGNMENT, ZERO_OFFSET,
|
||||
kExprGetLocal, 0, kExprBr, 2, kExprI8Const, 255, kExprSetLocal, 0,
|
||||
kExprI32Sub, kExprGetLocal, 0, kExprI8Const, 4, kExprI8Const, 0);
|
||||
BUILD(r, kExprLoop, kExprGetLocal, 0, kExprIf, kExprGetLocal, 0,
|
||||
kExprI32LoadMem, 0, 0, kExprIf, kExprI8Const, 255, kExprReturn, ARITY_1,
|
||||
kExprEnd, kExprGetLocal, 0, kExprI8Const, 4, kExprI32Sub, kExprSetLocal,
|
||||
0, kExprBr, ARITY_1, DEPTH_0, kExprEnd, kExprEnd, kExprI8Const, 0);
|
||||
|
||||
module.BlankMemory();
|
||||
CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
|
||||
@ -1695,7 +1733,7 @@ TEST(Run_Wasm_Infinite_Loop_not_taken1) {
|
||||
|
||||
TEST(Run_Wasm_Infinite_Loop_not_taken2) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(45)),
|
||||
BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(45)),
|
||||
WASM_INFINITE_LOOP)));
|
||||
// Run the code, but don't go into the infinite loop.
|
||||
CHECK_EQ(45, r.Call(1));
|
||||
@ -1726,14 +1764,13 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
|
||||
FunctionSig* sig = WasmOpcodes::Signature(opcode);
|
||||
|
||||
if (sig->parameter_count() == 1) {
|
||||
byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode), kExprGetLocal, 0};
|
||||
byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode)};
|
||||
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
|
||||
code + arraysize(code));
|
||||
} else {
|
||||
CHECK_EQ(2, sig->parameter_count());
|
||||
byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode),
|
||||
kExprGetLocal, 0,
|
||||
kExprGetLocal, 1};
|
||||
byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, kExprGetLocal, 1,
|
||||
static_cast<byte>(opcode)};
|
||||
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
|
||||
code + arraysize(code));
|
||||
}
|
||||
@ -1982,8 +2019,8 @@ TEST(Run_WasmCallF32StackParameter) {
|
||||
|
||||
// Build the calling function.
|
||||
WasmRunner<float> r(&module);
|
||||
BUILD(r, WASM_CALL_FUNCTION(
|
||||
index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
|
||||
BUILD(r, WASM_CALL_FUNCTIONN(
|
||||
19, index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
|
||||
WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
|
||||
WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
|
||||
WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
|
||||
@ -2007,13 +2044,13 @@ TEST(Run_WasmCallF64StackParameter) {
|
||||
|
||||
// Build the calling function.
|
||||
WasmRunner<double> r(&module);
|
||||
BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0),
|
||||
WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
|
||||
WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
|
||||
WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
|
||||
WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
|
||||
WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
|
||||
WASM_F64(256.5), WASM_F64(512.5)));
|
||||
BUILD(r, WASM_CALL_FUNCTIONN(19, index, WASM_F64(1.0), WASM_F64(2.0),
|
||||
WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
|
||||
WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
|
||||
WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
|
||||
WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
|
||||
WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
|
||||
WASM_F64(256.5), WASM_F64(512.5)));
|
||||
|
||||
float result = r.Call();
|
||||
CHECK_EQ(256.5, result);
|
||||
@ -2054,7 +2091,7 @@ TEST(Run_WasmCall_Int32Add) {
|
||||
|
||||
// Build the caller function.
|
||||
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
|
||||
BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
|
||||
FOR_INT32_INPUTS(i) {
|
||||
FOR_INT32_INPUTS(j) {
|
||||
@ -2076,7 +2113,7 @@ TEST(Run_WasmCall_Float32Sub) {
|
||||
|
||||
// Builder the caller function.
|
||||
WasmRunner<float> r(&module, MachineType::Float32(), MachineType::Float32());
|
||||
BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
|
||||
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, r.Call(*i, *j)); }
|
||||
@ -2165,23 +2202,30 @@ static void Run_WasmMixedCall_N(int start) {
|
||||
// Build the calling function.
|
||||
// =========================================================================
|
||||
WasmRunner<int32_t> r(&module);
|
||||
|
||||
std::vector<byte> code;
|
||||
ADD_CODE(code,
|
||||
static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET);
|
||||
ADD_CODE(code, WASM_ZERO);
|
||||
ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
|
||||
|
||||
// Load the offset for the store.
|
||||
ADD_CODE(code, WASM_ZERO);
|
||||
|
||||
// Load the arguments.
|
||||
for (int i = 0; i < num_params; i++) {
|
||||
int offset = (i + 1) * kElemSize;
|
||||
ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
|
||||
}
|
||||
|
||||
// Call the selector function.
|
||||
ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params),
|
||||
static_cast<byte>(index));
|
||||
|
||||
// Store the result in memory.
|
||||
ADD_CODE(code,
|
||||
static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
|
||||
ZERO_ALIGNMENT, ZERO_OFFSET);
|
||||
|
||||
// Return the expected value.
|
||||
ADD_CODE(code, WASM_I32V_2(kExpected));
|
||||
size_t end = code.size();
|
||||
code.push_back(0);
|
||||
r.Build(&code[0], &code[end]);
|
||||
|
||||
r.Build(&code[0], &code[0] + code.size());
|
||||
|
||||
// Run the code.
|
||||
for (int t = 0; t < 10; t++) {
|
||||
@ -2216,10 +2260,10 @@ TEST(Run_Wasm_AddCall) {
|
||||
byte local = r.AllocateLocal(kAstI32);
|
||||
BUILD(r, B2(WASM_SET_LOCAL(local, WASM_I8(99)),
|
||||
WASM_I32_ADD(
|
||||
WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0)),
|
||||
WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(local)))));
|
||||
WASM_CALL_FUNCTION2(t1.function_index_, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0)),
|
||||
WASM_CALL_FUNCTION2(t1.function_index_, WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(local)))));
|
||||
|
||||
CHECK_EQ(198, r.Call(0));
|
||||
CHECK_EQ(200, r.Call(1));
|
||||
@ -2230,7 +2274,7 @@ TEST(Run_Wasm_CountDown_expr) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, WASM_LOOP(
|
||||
3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
|
||||
WASM_BREAKV(0, WASM_GET_LOCAL(0))),
|
||||
WASM_BREAKV(1, WASM_GET_LOCAL(0))),
|
||||
WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
|
||||
WASM_CONTINUE(0)));
|
||||
CHECK_EQ(0, r.Call(1));
|
||||
@ -2241,7 +2285,7 @@ TEST(Run_Wasm_CountDown_expr) {
|
||||
|
||||
TEST(Run_Wasm_ExprBlock2a) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), WASM_I8(1)));
|
||||
BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))), WASM_I8(1)));
|
||||
CHECK_EQ(1, r.Call(0));
|
||||
CHECK_EQ(1, r.Call(1));
|
||||
}
|
||||
@ -2249,7 +2293,7 @@ TEST(Run_Wasm_ExprBlock2a) {
|
||||
|
||||
TEST(Run_Wasm_ExprBlock2b) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), WASM_I8(2)));
|
||||
BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))), WASM_I8(2)));
|
||||
CHECK_EQ(2, r.Call(0));
|
||||
CHECK_EQ(1, r.Call(1));
|
||||
}
|
||||
@ -2274,15 +2318,15 @@ TEST(Run_Wasm_ExprBlock2d) {
|
||||
TEST(Run_Wasm_ExprBlock_ManualSwitch) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
|
||||
WASM_BRV(0, WASM_I8(11))),
|
||||
WASM_BRV(1, WASM_I8(11))),
|
||||
WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
|
||||
WASM_BRV(0, WASM_I8(12))),
|
||||
WASM_BRV(1, WASM_I8(12))),
|
||||
WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
|
||||
WASM_BRV(0, WASM_I8(13))),
|
||||
WASM_BRV(1, WASM_I8(13))),
|
||||
WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
|
||||
WASM_BRV(0, WASM_I8(14))),
|
||||
WASM_BRV(1, WASM_I8(14))),
|
||||
WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
|
||||
WASM_BRV(0, WASM_I8(15))),
|
||||
WASM_BRV(1, WASM_I8(15))),
|
||||
WASM_I8(99)));
|
||||
CHECK_EQ(99, r.Call(0));
|
||||
CHECK_EQ(11, r.Call(1));
|
||||
@ -2338,7 +2382,7 @@ TEST(Run_Wasm_ExprBlock_if) {
|
||||
WasmRunner<int32_t> r(MachineType::Int32());
|
||||
|
||||
BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
|
||||
WASM_BRV(0, WASM_I8(14)))));
|
||||
WASM_BRV(1, WASM_I8(14)))));
|
||||
|
||||
CHECK_EQ(11, r.Call(1));
|
||||
CHECK_EQ(14, r.Call(0));
|
||||
@ -2352,10 +2396,9 @@ TEST(Run_Wasm_ExprBlock_nested_ifs) {
|
||||
1, WASM_IF_ELSE(
|
||||
WASM_GET_LOCAL(0),
|
||||
WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
|
||||
WASM_BRV(0, WASM_I8(12))),
|
||||
WASM_BRV(1, WASM_I8(12))),
|
||||
WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
|
||||
WASM_BRV(0, WASM_I8(14))))));
|
||||
|
||||
WASM_BRV(1, WASM_I8(14))))));
|
||||
|
||||
CHECK_EQ(11, r.Call(1, 1));
|
||||
CHECK_EQ(12, r.Call(1, 0));
|
||||
@ -2371,10 +2414,9 @@ TEST(Run_Wasm_ExprLoop_nested_ifs) {
|
||||
1, WASM_IF_ELSE(
|
||||
WASM_GET_LOCAL(0),
|
||||
WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)),
|
||||
WASM_BRV(1, WASM_I8(12))),
|
||||
WASM_BRV(3, WASM_I8(12))),
|
||||
WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)),
|
||||
WASM_BRV(1, WASM_I8(14))))));
|
||||
|
||||
WASM_BRV(3, WASM_I8(14))))));
|
||||
|
||||
CHECK_EQ(11, r.Call(1, 1));
|
||||
CHECK_EQ(12, r.Call(1, 0));
|
||||
@ -2382,7 +2424,6 @@ TEST(Run_Wasm_ExprLoop_nested_ifs) {
|
||||
CHECK_EQ(14, r.Call(0, 0));
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_SimpleCallIndirect) {
|
||||
TestSignatures sigs;
|
||||
TestingModule module;
|
||||
@ -2407,7 +2448,7 @@ TEST(Run_Wasm_SimpleCallIndirect) {
|
||||
|
||||
// Builder the caller function.
|
||||
WasmRunner<int32_t> r(&module, MachineType::Int32());
|
||||
BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
|
||||
BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
|
||||
|
||||
CHECK_EQ(88, r.Call(0));
|
||||
CHECK_EQ(44, r.Call(1));
|
||||
@ -2440,11 +2481,11 @@ TEST(Run_Wasm_MultipleCallIndirect) {
|
||||
// Builder the caller function.
|
||||
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32(),
|
||||
MachineType::Int32());
|
||||
BUILD(r,
|
||||
WASM_I32_ADD(WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(2)),
|
||||
WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
|
||||
WASM_GET_LOCAL(0))));
|
||||
BUILD(r, WASM_I32_ADD(
|
||||
WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(2)),
|
||||
WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
|
||||
WASM_GET_LOCAL(0))));
|
||||
|
||||
CHECK_EQ(5, r.Call(0, 1, 2));
|
||||
CHECK_EQ(19, r.Call(0, 1, 9));
|
||||
@ -2472,7 +2513,7 @@ TEST(Run_Wasm_CallIndirect_NoTable) {
|
||||
|
||||
// Builder the caller function.
|
||||
WasmRunner<int32_t> r(&module, MachineType::Int32());
|
||||
BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
|
||||
BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
|
||||
|
||||
CHECK_TRAP(r.Call(0));
|
||||
CHECK_TRAP(r.Call(1));
|
||||
@ -2793,11 +2834,11 @@ void CompileCallIndirectMany(LocalType param) {
|
||||
WasmFunctionCompiler t(sig, &module);
|
||||
|
||||
std::vector<byte> code;
|
||||
ADD_CODE(code, kExprCallIndirect, 1);
|
||||
ADD_CODE(code, kExprI8Const, 0);
|
||||
for (byte p = 0; p < num_params; p++) {
|
||||
ADD_CODE(code, kExprGetLocal, p);
|
||||
}
|
||||
ADD_CODE(code, kExprCallIndirect, static_cast<byte>(num_params), 1);
|
||||
|
||||
t.Build(&code[0], &code[0] + code.size());
|
||||
t.Compile();
|
||||
|
@ -4,6 +4,32 @@
|
||||
|
||||
// Flags: --expose-wasm
|
||||
|
||||
(function TestSwitch0() {
|
||||
function asmModule() {
|
||||
"use asm"
|
||||
|
||||
function caller() {
|
||||
var ret = 0;
|
||||
var x = 7;
|
||||
switch (x) {
|
||||
case 1: {
|
||||
return 0;
|
||||
}
|
||||
case 7: {
|
||||
ret = 5;
|
||||
break;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
return ret|0;
|
||||
}
|
||||
|
||||
return {caller:caller};
|
||||
}
|
||||
var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
|
||||
assertEquals(5, wasm.caller());
|
||||
})();
|
||||
|
||||
(function TestSwitch() {
|
||||
function asmModule() {
|
||||
"use asm"
|
||||
|
@ -23,6 +23,20 @@ function EmptyTest() {
|
||||
|
||||
assertWasm(11, EmptyTest);
|
||||
|
||||
function VoidReturnTest() {
|
||||
"use asm";
|
||||
function caller() {
|
||||
empty();
|
||||
return 19;
|
||||
}
|
||||
function empty() {
|
||||
var x = 0;
|
||||
if (x) return;
|
||||
}
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(19, VoidReturnTest);
|
||||
|
||||
function IntTest() {
|
||||
"use asm";
|
||||
@ -193,6 +207,55 @@ function TestReturnInWhileWithoutBraces() {
|
||||
assertWasm(7, TestReturnInWhileWithoutBraces);
|
||||
|
||||
|
||||
function TestBreakInIf() {
|
||||
"use asm";
|
||||
|
||||
function caller() {
|
||||
label: {
|
||||
if(1) break label;
|
||||
return 11;
|
||||
}
|
||||
return 12;
|
||||
}
|
||||
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(12, TestBreakInIf);
|
||||
|
||||
function TestBreakInIfInDoWhileFalse() {
|
||||
"use asm";
|
||||
|
||||
function caller() {
|
||||
do {
|
||||
if(1) break;
|
||||
return 11;
|
||||
} while(0);
|
||||
return 12;
|
||||
}
|
||||
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(12, TestBreakInIfInDoWhileFalse);
|
||||
|
||||
function TestBreakInElse() {
|
||||
"use asm";
|
||||
|
||||
function caller() {
|
||||
do {
|
||||
if(0) ;
|
||||
else break;
|
||||
return 14;
|
||||
} while(0);
|
||||
return 15;
|
||||
}
|
||||
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(15, TestBreakInElse);
|
||||
|
||||
function TestBreakInWhile() {
|
||||
"use asm";
|
||||
|
||||
@ -209,6 +272,22 @@ function TestBreakInWhile() {
|
||||
assertWasm(8, TestBreakInWhile);
|
||||
|
||||
|
||||
function TestBreakInIfInWhile() {
|
||||
"use asm";
|
||||
|
||||
function caller() {
|
||||
while(1) {
|
||||
if (1) break;
|
||||
else break;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(8, TestBreakInIfInWhile);
|
||||
|
||||
function TestBreakInNestedWhile() {
|
||||
"use asm";
|
||||
|
||||
|
@ -37,7 +37,6 @@ function assertFunction(module, func) {
|
||||
assertFalse(exp === null);
|
||||
assertFalse(exp === 0);
|
||||
assertEquals("function", typeof exp);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
@ -47,10 +46,10 @@ function assertFunction(module, func) {
|
||||
|
||||
builder.addMemory(1, 1, true);
|
||||
builder.addFunction("sub", [kAstI64, kAstI64, kAstI64])
|
||||
.addBody([
|
||||
kExprI64Sub, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
.addBody([ // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI64Sub]) // --
|
||||
.exportFunc()
|
||||
|
||||
var module = builder.instantiate();
|
||||
@ -70,9 +69,10 @@ function assertFunction(module, func) {
|
||||
builder.addMemory(1, 1, true);
|
||||
builder.addFunction("sub", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([
|
||||
kExprI32Sub, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI32Sub, // --
|
||||
])
|
||||
.exportFunc()
|
||||
|
||||
var module = builder.instantiate();
|
||||
@ -111,9 +111,10 @@ function assertFunction(module, func) {
|
||||
builder.addMemory(kPages, kPages, true);
|
||||
builder.addFunction("flt", [kAstI32, kAstF64, kAstF64])
|
||||
.addBody([
|
||||
kExprF64Lt, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprF64Lt // --
|
||||
]) // --
|
||||
.exportFunc();
|
||||
|
||||
var module = builder.instantiate();
|
||||
|
@ -34,7 +34,11 @@ function makeBinop(opcode) {
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
||||
builder.addFunction("main", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([opcode, kExprGetLocal, 0, kExprGetLocal, 1])
|
||||
.addBody([
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
opcode, // --
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
return builder.instantiate().exports.main;
|
||||
|
@ -13,9 +13,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
builder.addFunction("main", [kAstI32])
|
||||
.addBody([
|
||||
kExprReturn,
|
||||
kExprI8Const,
|
||||
kReturnValue])
|
||||
kReturnValue,
|
||||
kExprReturn, kArity1
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
var module = builder.instantiate();
|
||||
@ -33,9 +34,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
builder.addFunction("main", [kAstI32])
|
||||
.addBody([
|
||||
kExprReturn,
|
||||
kExprI8Const,
|
||||
kReturnValue])
|
||||
kReturnValue,
|
||||
kExprReturn, kArity1
|
||||
])
|
||||
.exportAs("blah")
|
||||
.exportAs("foo");
|
||||
|
||||
|
@ -14,9 +14,10 @@ function testCallFFI(ffi) {
|
||||
builder.addImport("fun", sig_index);
|
||||
builder.addFunction("main", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprCallFunction, kArity2, 0, // --
|
||||
]) // --
|
||||
.exportFunc();
|
||||
|
||||
var module = builder.instantiate(ffi);
|
||||
|
@ -14,9 +14,10 @@ function testCallFFI(func, check) {
|
||||
builder.addImport("func", sig_index);
|
||||
builder.addFunction("main", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprCallImport, kArity2, 0 // --
|
||||
]) // --
|
||||
.exportFunc();
|
||||
|
||||
var main = builder.instantiate({func: func}).exports.main;
|
||||
@ -187,11 +188,11 @@ function testCallBinopVoid(type, func, check) {
|
||||
builder.addImport("func", [kAstStmt, type, type]);
|
||||
builder.addFunction("main", [kAstI32, type, type])
|
||||
.addBody([
|
||||
kExprBlock, 2, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI8Const, 99]) // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprCallImport, kArity2, 0, // --
|
||||
kExprI8Const, 99 // --
|
||||
]) // --
|
||||
.exportFunc()
|
||||
|
||||
var main = builder.instantiate(ffi).exports.main;
|
||||
@ -244,11 +245,11 @@ function testCallPrint() {
|
||||
builder.addImport("print", [kAstStmt, kAstF64]);
|
||||
builder.addFunction("main", [kAstStmt, kAstF64])
|
||||
.addBody([
|
||||
kExprBlock, 2, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprI8Const, 97, // --
|
||||
kExprCallImport, 1, // --
|
||||
kExprGetLocal, 0]) // --
|
||||
kExprI8Const, 97, // --
|
||||
kExprCallImport, kArity1, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprCallImport, kArity1, 1 // --
|
||||
]) // --
|
||||
.exportFunc()
|
||||
|
||||
var main = builder.instantiate({print: print}).exports.main;
|
||||
|
@ -17,7 +17,6 @@ function makeFFI(func, t) {
|
||||
// the different parts of the stack.
|
||||
builder.addFunction("main", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprGetLocal, 2, // --
|
||||
@ -28,7 +27,7 @@ function makeFFI(func, t) {
|
||||
kExprGetLocal, 7, // --
|
||||
kExprGetLocal, 8, // --
|
||||
kExprGetLocal, 9, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprCallImport, 10, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprGetLocal, 2, // --
|
||||
@ -38,7 +37,8 @@ function makeFFI(func, t) {
|
||||
kExprGetLocal, 6, // --
|
||||
kExprGetLocal, 7, // --
|
||||
kExprGetLocal, 8, // --
|
||||
kExprGetLocal, 9 // --
|
||||
kExprGetLocal, 9, // --
|
||||
kExprCallImport, 10, 0 // --
|
||||
]) // --
|
||||
.exportFunc();
|
||||
|
||||
|
@ -14,9 +14,9 @@ function testCallImport(func, check) {
|
||||
builder.addImport("func", sig_index);
|
||||
builder.addFunction("main", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprCallImport, 2, 0]) // --
|
||||
.exportAs("main");
|
||||
|
||||
var main = builder.instantiate({func: func}).exports.main;
|
||||
@ -189,11 +189,11 @@ function testCallBinopVoid(type, func, check) {
|
||||
builder.addImport("func", [kAstStmt, type, type]);
|
||||
builder.addFunction("main", [kAstI32, type, type])
|
||||
.addBody([
|
||||
kExprBlock, 2, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI8Const, 99])
|
||||
kExprCallImport, 2, 0, // --
|
||||
kExprI8Const, 99, // --
|
||||
])
|
||||
.exportFunc("main");
|
||||
|
||||
var main = builder.instantiate(ffi).exports.main;
|
||||
@ -245,11 +245,11 @@ function testCallPrint() {
|
||||
builder.addImport("print", [kAstStmt, kAstF64]);
|
||||
builder.addFunction("main", [kAstStmt, kAstF64])
|
||||
.addBody([
|
||||
kExprBlock, 2, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprI8Const, 97, // --
|
||||
kExprCallImport, 1, // --
|
||||
kExprGetLocal, 0]) // --
|
||||
kExprI8Const, 97, // --
|
||||
kExprCallImport, kArity1, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprCallImport, kArity1, 1 // --
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
var main = builder.instantiate({print: print}).exports.main;
|
||||
@ -270,9 +270,10 @@ function testCallImport2(foo, bar, expected) {
|
||||
builder.addImport("bar", [kAstI32]);
|
||||
builder.addFunction("main", [kAstI32])
|
||||
.addBody([
|
||||
kExprCallImport, kArity0, 0, // --
|
||||
kExprCallImport, kArity0, 1, // --
|
||||
kExprI32Add, // --
|
||||
kExprCallImport, 0, // --
|
||||
kExprCallImport, 1]) // --
|
||||
]) // --
|
||||
.exportFunc();
|
||||
|
||||
var main = builder.instantiate({foo: foo, bar: bar}).exports.main;
|
||||
|
@ -14,18 +14,21 @@ var module = (function () {
|
||||
builder.addImport("add", sig_index);
|
||||
builder.addFunction("add", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, kExprGetLocal, 0, kExprGetLocal, 1
|
||||
kExprGetLocal, 0, kExprGetLocal, 1, kExprCallImport, kArity2, 0
|
||||
]);
|
||||
builder.addFunction("sub", sig_index)
|
||||
.addBody([
|
||||
kExprI32Sub, kExprGetLocal, 0, kExprGetLocal, 1
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprI32Sub, // --
|
||||
]);
|
||||
builder.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
|
||||
.addBody([
|
||||
kExprCallIndirect, sig_index,
|
||||
kExprGetLocal, 0,
|
||||
kExprGetLocal, 1,
|
||||
kExprGetLocal, 2])
|
||||
kExprGetLocal, 2,
|
||||
kExprCallIndirect, kArity2, sig_index
|
||||
])
|
||||
.exportFunc()
|
||||
builder.appendToFunctionTable([0, 1, 2]);
|
||||
|
||||
|
@ -15,17 +15,25 @@ function genModule(memory) {
|
||||
builder.addMemory(1, 1, true);
|
||||
builder.addFunction("main", [kAstI32, kAstI32])
|
||||
.addBody([
|
||||
kExprBlock,2,
|
||||
kExprLoop,1,
|
||||
kExprIf,
|
||||
// main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
|
||||
kExprLoop,
|
||||
kExprGetLocal,0,
|
||||
kExprIf,
|
||||
kExprGetLocal,0,
|
||||
kExprBr, 0,
|
||||
kExprIfElse,
|
||||
kExprI32LoadMem,0,0,kExprGetLocal,0,
|
||||
kExprBr,2, kExprI8Const, 255,
|
||||
kExprSetLocal,0,
|
||||
kExprI32Sub,kExprGetLocal,0,kExprI8Const,4,
|
||||
kExprI8Const,0])
|
||||
kExprI32LoadMem,0,0,
|
||||
kExprIf,
|
||||
kExprI8Const,255,
|
||||
kExprReturn, kArity1,
|
||||
kExprEnd,
|
||||
kExprGetLocal,0,
|
||||
kExprI8Const,4,
|
||||
kExprI32Sub,
|
||||
kExprSetLocal,0,
|
||||
kExprBr, kArity1, 1,
|
||||
kExprEnd,
|
||||
kExprEnd,
|
||||
kExprI8Const,0
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
return builder.instantiate(null, memory);
|
||||
@ -122,12 +130,14 @@ function testOOBThrows() {
|
||||
builder.addMemory(1, 1, true);
|
||||
builder.addFunction("geti", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([
|
||||
kExprI32StoreMem, 0, 0, kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprGetLocal, 1
|
||||
kExprGetLocal, 0,
|
||||
kExprGetLocal, 1,
|
||||
kExprI32LoadMem, 0, 0,
|
||||
kExprI32StoreMem, 0, 0
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
var module = builder.instantiate();
|
||||
|
||||
var offset;
|
||||
|
||||
function read() { return module.exports.geti(0, offset); }
|
||||
|
@ -39,7 +39,7 @@ var builder = new WasmModuleBuilder();
|
||||
builder.addImport("func", [kAstStmt]);
|
||||
|
||||
builder.addFunction("main", [kAstStmt])
|
||||
.addBody([kExprCallImport, 0])
|
||||
.addBody([kExprCallImport, kArity0, 0])
|
||||
.exportAs("main");
|
||||
|
||||
builder.addFunction("exec_unreachable", [kAstStmt])
|
||||
@ -49,12 +49,12 @@ builder.addFunction("exec_unreachable", [kAstStmt])
|
||||
// make this function unnamed, just to test also this case
|
||||
var mem_oob_func = builder.addFunction(undefined, [kAstStmt])
|
||||
// access the memory at offset -1
|
||||
.addBody([kExprI32LoadMem8S, 0, 0, kExprI32Const, 0x7f])
|
||||
.addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
|
||||
.exportAs("mem_out_of_bounds");
|
||||
|
||||
// call the mem_out_of_bounds function, in order to have two WASM stack frames
|
||||
builder.addFunction("call_mem_out_of_bounds", [kAstStmt])
|
||||
.addBody([kExprCallFunction, mem_oob_func.index])
|
||||
.addBody([kExprCallFunction, kArity0, mem_oob_func.index])
|
||||
.exportAs("call_mem_out_of_bounds");
|
||||
|
||||
var module = builder.instantiate({func: STACK});
|
||||
|
@ -14,9 +14,10 @@ function makeFFI(func) {
|
||||
builder.addImport("func", sig_index);
|
||||
builder.addFunction("main", sig_index)
|
||||
.addBody([
|
||||
kExprCallImport, 0, // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1]) // --
|
||||
kExprGetLocal, 0, // --
|
||||
kExprGetLocal, 1, // --
|
||||
kExprCallImport, kArity2, 0, // --
|
||||
])
|
||||
.exportFunc()
|
||||
|
||||
return builder.instantiate({func: func}).exports.main;
|
||||
|
@ -79,7 +79,7 @@ assertFails([kAstI32, kAstI32, kAstF32, kAstF64], [kExprGetLocal, 0]);
|
||||
builder.addMemory(12, 12, true);
|
||||
|
||||
var func = builder.addFunction("", [kAstStmt])
|
||||
.addBody([kExprI32StoreMem, 0, 0, kExprI8Const, 0, kExprI8Const, 77]);
|
||||
.addBody([kExprI8Const, 0, kExprI8Const, 77, kExprI32StoreMem, 0, 0]);
|
||||
|
||||
builder.addStart(func.index);
|
||||
|
||||
@ -102,7 +102,7 @@ assertFails([kAstI32, kAstI32, kAstF32, kAstF64], [kExprGetLocal, 0]);
|
||||
|
||||
builder.addImport("foo", sig_index);
|
||||
var func = builder.addFunction("", sig_index)
|
||||
.addBody([kExprCallImport, 0]);
|
||||
.addBody([kExprCallImport, kArity0, 0]);
|
||||
|
||||
builder.addStart(func.index);
|
||||
|
||||
|
@ -25,7 +25,7 @@ var debug = false;
|
||||
var module = new WasmModuleBuilder();
|
||||
var index = module.addImport("print", [kAstStmt, kAstI32]);
|
||||
module.addFunction("foo", [kAstStmt])
|
||||
.addBody([kExprCallImport, index, kExprI8Const, 13])
|
||||
.addBody([kExprI8Const, 13, kExprCallImport, kArity1, index])
|
||||
.exportAs("main");
|
||||
|
||||
var buffer = module.toBuffer(debug);
|
||||
@ -38,7 +38,7 @@ var debug = false;
|
||||
var module = new WasmModuleBuilder();
|
||||
module.addFunction(undefined, [kAstI32, kAstI32])
|
||||
.addLocals({i32_count: 1})
|
||||
.addBody([kExprSetLocal, 1, kExprGetLocal, 0])
|
||||
.addBody([kExprGetLocal, 0, kExprSetLocal, 1])
|
||||
.exportAs("main");
|
||||
|
||||
var buffer = module.toBuffer(debug);
|
||||
@ -60,7 +60,7 @@ var debug = false;
|
||||
var module = new WasmModuleBuilder();
|
||||
module.addFunction(undefined, [p.type, p.type])
|
||||
.addLocals(p.locals)
|
||||
.addBody([kExprSetLocal, 1, kExprGetLocal, 0])
|
||||
.addBody([kExprGetLocal, 0, kExprSetLocal, 1])
|
||||
.exportAs("main");
|
||||
|
||||
var buffer = module.toBuffer(debug);
|
||||
@ -73,9 +73,9 @@ var debug = false;
|
||||
(function CallTest() {
|
||||
var module = new WasmModuleBuilder();
|
||||
module.addFunction("add", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
|
||||
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
|
||||
module.addFunction("main", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([kExprCallFunction, 0, kExprGetLocal, 0, kExprGetLocal, 1])
|
||||
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, kArity2, 0])
|
||||
.exportAs("main");
|
||||
|
||||
var instance = module.instantiate();
|
||||
@ -86,10 +86,10 @@ var debug = false;
|
||||
(function IndirectCallTest() {
|
||||
var module = new WasmModuleBuilder();
|
||||
module.addFunction("add", [kAstI32, kAstI32, kAstI32])
|
||||
.addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
|
||||
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
|
||||
module.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
|
||||
.addBody([kExprCallIndirect, 0, kExprGetLocal,
|
||||
0, kExprGetLocal, 1, kExprGetLocal, 2])
|
||||
.addBody([kExprGetLocal,
|
||||
0, kExprGetLocal, 1, kExprGetLocal, 2, kExprCallIndirect, kArity2, 0])
|
||||
.exportAs("main");
|
||||
module.appendToFunctionTable([0]);
|
||||
|
||||
@ -103,7 +103,7 @@ var debug = false;
|
||||
var module = new WasmModuleBuilder();
|
||||
module.addMemory(1, 1, false);
|
||||
module.addFunction("load", [kAstI32, kAstI32])
|
||||
.addBody([kExprI32LoadMem, 0, 0, kExprGetLocal, 0])
|
||||
.addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0])
|
||||
.exportAs("load");
|
||||
module.addDataSegment(0, [9, 9, 9, 9], true);
|
||||
|
||||
@ -143,7 +143,7 @@ var debug = false;
|
||||
var module = new WasmModuleBuilder();
|
||||
var index = module.addImportWithModule("mod", "print", [kAstStmt, kAstI32]);
|
||||
module.addFunction("foo", [kAstStmt])
|
||||
.addBody([kExprCallImport, index, kExprI8Const, 19])
|
||||
.addBody([kExprI8Const, 19, kExprCallImport, kArity1, index])
|
||||
.exportAs("main");
|
||||
|
||||
var buffer = module.toBuffer(debug);
|
||||
|
@ -25,7 +25,7 @@ try {
|
||||
var data = bytes(
|
||||
0, kAstI32, // signature
|
||||
kDeclNoLocals, // --
|
||||
kExprBlock, 2, kExprNop, kExprNop // body
|
||||
kExprBlock, kExprNop, kExprNop, kExprEnd // body
|
||||
);
|
||||
|
||||
Wasm.verifyFunction(data);
|
||||
|
@ -65,6 +65,11 @@ var kDeclFunctionSignatures = 0x0a;
|
||||
var kDeclFunctionBodies = 0x0b;
|
||||
var kDeclNames = 0x0c;
|
||||
|
||||
var kArity0 = 0;
|
||||
var kArity1 = 1;
|
||||
var kArity2 = 2;
|
||||
var kArity3 = 3;
|
||||
|
||||
var section_names = [
|
||||
"memory", "signatures", "functions", "globals", "data_segments",
|
||||
"function_table", "end", "start_function", "import_table", "export_table",
|
||||
@ -88,26 +93,27 @@ var kExprNop = 0x00;
|
||||
var kExprBlock = 0x01;
|
||||
var kExprLoop = 0x02;
|
||||
var kExprIf = 0x03;
|
||||
var kExprIfElse = 0x04;
|
||||
var kExprElse = 0x04;
|
||||
var kExprSelect = 0x05;
|
||||
var kExprBr = 0x06;
|
||||
var kExprBrIf = 0x07;
|
||||
var kExprTableSwitch = 0x08;
|
||||
var kExprReturn = 0x14;
|
||||
var kExprUnreachable = 0x15;
|
||||
var kExprBrTable = 0x08;
|
||||
var kExprReturn = 0x09;
|
||||
var kExprUnreachable = 0x0a;
|
||||
var kExprEnd = 0x0f;
|
||||
|
||||
var kExprI8Const = 0x09;
|
||||
var kExprI32Const = 0x0a;
|
||||
var kExprI64Const = 0x0b;
|
||||
var kExprF64Const = 0x0c;
|
||||
var kExprF32Const = 0x0d;
|
||||
var kExprGetLocal = 0x0e;
|
||||
var kExprSetLocal = 0x0f;
|
||||
var kExprLoadGlobal = 0x10;
|
||||
var kExprStoreGlobal = 0x11;
|
||||
var kExprCallFunction = 0x12;
|
||||
var kExprCallIndirect = 0x13;
|
||||
var kExprCallImport = 0x1F;
|
||||
var kExprI32Const = 0x10;
|
||||
var kExprI64Const = 0x11;
|
||||
var kExprF64Const = 0x12;
|
||||
var kExprF32Const = 0x13;
|
||||
var kExprGetLocal = 0x14;
|
||||
var kExprSetLocal = 0x15;
|
||||
var kExprCallFunction = 0x16;
|
||||
var kExprCallIndirect = 0x17;
|
||||
var kExprCallImport = 0x18;
|
||||
var kExprI8Const = 0xcb;
|
||||
var kExprLoadGlobal = 0xcc;
|
||||
var kExprStoreGlobal = 0xcd;
|
||||
|
||||
var kExprI32LoadMem8S = 0x20;
|
||||
var kExprI32LoadMem8U = 0x21;
|
||||
|
@ -10,3 +10,4 @@ assertEquals("function", typeof Wasm.verifyModule);
|
||||
assertEquals("function", typeof Wasm.verifyFunction);
|
||||
assertEquals("function", typeof Wasm.instantiateModule);
|
||||
assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
|
||||
assertFalse(undefined == Wasm.experimentalVersion);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -184,7 +184,7 @@ TEST_F(WasmLoopAssignmentAnalyzerTest, Loop2) {
|
||||
WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
|
||||
WASM_GET_LOCAL(kIter))};
|
||||
|
||||
BitVector* assigned = Analyze(code + 2, code + arraysize(code));
|
||||
BitVector* assigned = Analyze(code + 1, code + arraysize(code));
|
||||
for (int j = 0; j < assigned->length(); j++) {
|
||||
bool expected = j == kIter || j == kSum;
|
||||
CHECK_EQ(expected, assigned->Contains(j));
|
||||
|
@ -58,46 +58,46 @@ TEST_F(WasmMacroGenTest, Statements) {
|
||||
|
||||
EXPECT_SIZE(7, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(4, WASM_IF(WASM_ZERO, WASM_NOP));
|
||||
EXPECT_SIZE(5, WASM_IF(WASM_ZERO, WASM_NOP));
|
||||
|
||||
EXPECT_SIZE(5, WASM_IF_ELSE(WASM_ZERO, WASM_NOP, WASM_NOP));
|
||||
EXPECT_SIZE(7, WASM_IF_ELSE(WASM_ZERO, WASM_NOP, WASM_NOP));
|
||||
|
||||
EXPECT_SIZE(5, WASM_SELECT(WASM_ZERO, WASM_NOP, WASM_NOP));
|
||||
|
||||
EXPECT_SIZE(3, WASM_BR(0));
|
||||
EXPECT_SIZE(4, WASM_BR(0));
|
||||
EXPECT_SIZE(5, WASM_BR_IF(0, WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(3, WASM_BLOCK(1, WASM_NOP));
|
||||
EXPECT_SIZE(4, WASM_BLOCK(2, WASM_NOP, WASM_NOP));
|
||||
EXPECT_SIZE(5, WASM_BLOCK(3, WASM_NOP, WASM_NOP, WASM_NOP));
|
||||
|
||||
EXPECT_SIZE(5, WASM_INFINITE_LOOP);
|
||||
EXPECT_SIZE(6, WASM_INFINITE_LOOP);
|
||||
|
||||
EXPECT_SIZE(3, WASM_LOOP(1, WASM_NOP));
|
||||
EXPECT_SIZE(4, WASM_LOOP(2, WASM_NOP, WASM_NOP));
|
||||
EXPECT_SIZE(5, WASM_LOOP(3, WASM_NOP, WASM_NOP, WASM_NOP));
|
||||
EXPECT_SIZE(5, WASM_LOOP(1, WASM_BR(0)));
|
||||
EXPECT_SIZE(6, WASM_LOOP(1, WASM_BR(0)));
|
||||
EXPECT_SIZE(7, WASM_LOOP(1, WASM_BR_IF(0, WASM_ZERO)));
|
||||
|
||||
EXPECT_SIZE(1, WASM_RETURN0);
|
||||
EXPECT_SIZE(3, WASM_RETURN(WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_RETURN(WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(2, WASM_RETURN0);
|
||||
EXPECT_SIZE(4, WASM_RETURN1(WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(1, WASM_UNREACHABLE);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WasmMacroGenTest, MacroStatements) {
|
||||
EXPECT_SIZE(8, WASM_WHILE(WASM_I8(0), WASM_NOP));
|
||||
EXPECT_SIZE(10, WASM_WHILE(WASM_I8(0), WASM_NOP));
|
||||
EXPECT_SIZE(7, WASM_INC_LOCAL(0));
|
||||
EXPECT_SIZE(7, WASM_INC_LOCAL_BY(0, 3));
|
||||
|
||||
EXPECT_SIZE(3, WASM_BREAK(0));
|
||||
EXPECT_SIZE(3, WASM_CONTINUE(0));
|
||||
EXPECT_SIZE(4, WASM_BREAK(0));
|
||||
EXPECT_SIZE(4, WASM_CONTINUE(0));
|
||||
}
|
||||
|
||||
TEST_F(WasmMacroGenTest, BrTable) {
|
||||
EXPECT_SIZE(8, WASM_BR_TABLE(WASM_ZERO, 1, BR_TARGET(1)));
|
||||
EXPECT_SIZE(9, WASM_BR_TABLE(WASM_ZERO, 1, BR_TARGET(1)));
|
||||
EXPECT_SIZE(11, WASM_BR_TABLEV(WASM_ZERO, WASM_ZERO, 1, BR_TARGET(1)));
|
||||
}
|
||||
|
||||
|
||||
@ -114,8 +114,8 @@ TEST_F(WasmMacroGenTest, Expressions) {
|
||||
|
||||
EXPECT_SIZE(3, WASM_NOT(WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(4, WASM_BRV(1, WASM_ZERO));
|
||||
EXPECT_SIZE(6, WASM_BRV_IF(1, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_BRV(1, WASM_ZERO));
|
||||
EXPECT_SIZE(7, WASM_BRV_IF(1, WASM_ZERO, WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(4, WASM_BLOCK(1, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_BLOCK(2, WASM_NOP, WASM_ZERO));
|
||||
@ -127,33 +127,32 @@ TEST_F(WasmMacroGenTest, Expressions) {
|
||||
}
|
||||
|
||||
TEST_F(WasmMacroGenTest, CallFunction) {
|
||||
EXPECT_SIZE(2, WASM_CALL_FUNCTION0(0));
|
||||
EXPECT_SIZE(2, WASM_CALL_FUNCTION0(1));
|
||||
EXPECT_SIZE(2, WASM_CALL_FUNCTION0(11));
|
||||
EXPECT_SIZE(3, WASM_CALL_FUNCTION0(0));
|
||||
EXPECT_SIZE(3, WASM_CALL_FUNCTION0(1));
|
||||
EXPECT_SIZE(3, WASM_CALL_FUNCTION0(11));
|
||||
|
||||
EXPECT_SIZE(4, WASM_CALL_FUNCTION(0, WASM_ZERO));
|
||||
EXPECT_SIZE(6, WASM_CALL_FUNCTION(1, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_CALL_FUNCTION1(0, WASM_ZERO));
|
||||
EXPECT_SIZE(7, WASM_CALL_FUNCTION2(1, WASM_ZERO, WASM_ZERO));
|
||||
}
|
||||
|
||||
TEST_F(WasmMacroGenTest, CallImport) {
|
||||
EXPECT_SIZE(2, WASM_CALL_IMPORT0(0));
|
||||
EXPECT_SIZE(2, WASM_CALL_IMPORT0(1));
|
||||
EXPECT_SIZE(2, WASM_CALL_IMPORT0(11));
|
||||
EXPECT_SIZE(3, WASM_CALL_IMPORT0(0));
|
||||
EXPECT_SIZE(3, WASM_CALL_IMPORT0(1));
|
||||
EXPECT_SIZE(3, WASM_CALL_IMPORT0(11));
|
||||
|
||||
EXPECT_SIZE(4, WASM_CALL_IMPORT(0, WASM_ZERO));
|
||||
EXPECT_SIZE(6, WASM_CALL_IMPORT(1, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_CALL_IMPORT1(0, WASM_ZERO));
|
||||
EXPECT_SIZE(7, WASM_CALL_IMPORT2(1, WASM_ZERO, WASM_ZERO));
|
||||
}
|
||||
|
||||
TEST_F(WasmMacroGenTest, CallIndirect) {
|
||||
EXPECT_SIZE(4, WASM_CALL_INDIRECT0(0, WASM_ZERO));
|
||||
EXPECT_SIZE(4, WASM_CALL_INDIRECT0(1, WASM_ZERO));
|
||||
EXPECT_SIZE(4, WASM_CALL_INDIRECT0(11, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_CALL_INDIRECT0(0, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_CALL_INDIRECT0(1, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_CALL_INDIRECT0(11, WASM_ZERO));
|
||||
|
||||
EXPECT_SIZE(6, WASM_CALL_INDIRECT(0, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(8, WASM_CALL_INDIRECT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(7, WASM_CALL_INDIRECT1(0, WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(9, WASM_CALL_INDIRECT2(1, WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WasmMacroGenTest, Int32Ops) {
|
||||
EXPECT_SIZE(5, WASM_I32_ADD(WASM_ZERO, WASM_ZERO));
|
||||
EXPECT_SIZE(5, WASM_I32_SUB(WASM_ZERO, WASM_ZERO));
|
||||
|
Loading…
Reference in New Issue
Block a user