[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:
titzer 2016-04-29 02:15:26 -07:00 committed by Commit bot
parent 7595dfd949
commit 2aa4656eeb
35 changed files with 2365 additions and 2021 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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_

View File

@ -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";

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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"

View File

@ -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";

View File

@ -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();

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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]);

View File

@ -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); }

View File

@ -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});

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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));

View File

@ -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));