diff --git a/wasmlib.lua b/wasmlib.lua index 81f9137..47c9087 100644 --- a/wasmlib.lua +++ b/wasmlib.lua @@ -277,6 +277,20 @@ function wasmlib.VM:i64_const() table.insert(self.stack, self:readarg64()) end +function wasmlib.VM:invoke(funcIndex) + local fr = frame.StackFrame:new(funcIndex) + local f = self.functions[funcIndex] + local sig = self.types[f.typeidx] + for i = 1, #sig.arguments do + fr.locals[#sig.arguments - i] = table.remove(self.stack) + end + table.insert(self.stackFrames, fr) +end + +function wasmlib.VM:ret() + table.remove(self.stackFrames) +end + function wasmlib.VM:step() local curFrame = self:topFrame() local body = self.functions[curFrame.funcIndex].body @@ -286,8 +300,8 @@ function wasmlib.VM:step() local c = constants.opcodes local optable = { -- control - [c.OP_UNREACHABLE] = function() error("unreachable") end, - [c.OP_NOP] = function() end, + [c.OP_UNREACHABLE] = function() error("unreachable") end, + [c.OP_NOP] = function() end, -- BLOCK -- LOOP -- IF @@ -296,107 +310,107 @@ function wasmlib.VM:step() -- BR -- BR_IF -- BR_TABLE - [c.OP_RETURN] = function() self:ret() end, - [c.OP_CALL] = function() self:call() end, + [c.OP_RETURN] = function() self:ret() end, + [c.OP_CALL] = function() self:call() end, -- CALL_INDIRECT -- parametric - [c.OP_DROP] = function() table.remove(self.stack) end, - [c.OP_SELECT] = function() self:triop(ops.select) end, + [c.OP_DROP] = function() table.remove(self.stack) end, + [c.OP_SELECT] = function() self:triop(ops.select) end, -- variable - [c.OP_LOCAL_GET] = function() self:local_get() end, - [c.OP_LOCAL_SET] = function() self:local_set() end, - [c.OP_LOCAL_TEE] = function() self:local_tee() end, - [c.OP_GLOBAL_GET] = function() self:global_get() end, - [c.OP_GLOBAL_SET] = function() self:global_set() end, + [c.OP_LOCAL_GET] = function() self:local_get() end, + [c.OP_LOCAL_SET] = function() self:local_set() end, + [c.OP_LOCAL_TEE] = function() self:local_tee() end, + [c.OP_GLOBAL_GET] = function() self:global_get() end, + [c.OP_GLOBAL_SET] = function() self:global_set() end, -- memory - [c.OP_I32_LOAD] = function() self:i32_load() end, - [c.OP_I64_LOAD] = function() self:i64_load() end, + [c.OP_I32_LOAD] = function() self:i32_load() end, + [c.OP_I64_LOAD] = function() self:i64_load() end, -- [float instrs] - [c.OP_I32_LOAD8_S] = function() self:i32_load8_s() end, - [c.OP_I32_LOAD8_U] = function() self:i32_load8_u() end, - [c.OP_I32_LOAD16_S] = function() self:i32_load16_s() end, - [c.OP_I32_LOAD16_U] = function() self:i32_load16_u() end, - [c.OP_I64_LOAD8_S] = function() self:i64_load8_s() end, - [c.OP_I64_LOAD8_U] = function() self:i64_load8_u() end, - [c.OP_I64_LOAD16_S] = function() self:i64_load16_s() end, - [c.OP_I64_LOAD16_U] = function() self:i64_load16_u() end, - [c.OP_I64_LOAD32_S] = function() self:i64_load32_s() end, - [c.OP_I64_LOAD32_U] = function() self:i64_load32_u() end, - [c.OP_I32_STORE] = function() self:i32_store() end, - [c.OP_I64_STORE] = function() self:i64_store() end, + [c.OP_I32_LOAD8_S] = function() self:i32_load8_s() end, + [c.OP_I32_LOAD8_U] = function() self:i32_load8_u() end, + [c.OP_I32_LOAD16_S] = function() self:i32_load16_s() end, + [c.OP_I32_LOAD16_U] = function() self:i32_load16_u() end, + [c.OP_I64_LOAD8_S] = function() self:i64_load8_s() end, + [c.OP_I64_LOAD8_U] = function() self:i64_load8_u() end, + [c.OP_I64_LOAD16_S] = function() self:i64_load16_s() end, + [c.OP_I64_LOAD16_U] = function() self:i64_load16_u() end, + [c.OP_I64_LOAD32_S] = function() self:i64_load32_s() end, + [c.OP_I64_LOAD32_U] = function() self:i64_load32_u() end, + [c.OP_I32_STORE] = function() self:i32_store() end, + [c.OP_I64_STORE] = function() self:i64_store() end, -- [floart instrs] - [c.OP_I32_STORE8] = function() self:i32_store8() end, - [c.OP_I32_STORE16] = function() self:i32_store16() end, - [c.OP_I64_STORE8] = function() self:i64_store8() end, - [c.OP_I64_STORE16] = function() self:i64_store16() end, - [c.OP_I64_STORE32] = function() self:i64_store32() end, - [c.OP_MEMORY_SIZE] = function() self:memory_size() end, - [c.OP_MEMORY_GROW] = function() self:memory_grow() end, + [c.OP_I32_STORE8] = function() self:i32_store8() end, + [c.OP_I32_STORE16] = function() self:i32_store16() end, + [c.OP_I64_STORE8] = function() self:i64_store8() end, + [c.OP_I64_STORE16] = function() self:i64_store16() end, + [c.OP_I64_STORE32] = function() self:i64_store32() end, + [c.OP_MEMORY_SIZE] = function() self:memory_size() end, + [c.OP_MEMORY_GROW] = function() self:memory_grow() end, -- constants - [c.OP_I32_CONST] = function() self:i32_const() end, - [c.OP_I64_CONST] = function() self:i64_const() end, + [c.OP_I32_CONST] = function() self:i32_const() end, + [c.OP_I64_CONST] = function() self:i64_const() end, -- [float consts] -- i32 comparisons - [c.OP_I32_EQZ] = function() self:unop (ops.i32_eqz) end, - [c.OP_I32_EQ] = function() self:binop(ops.i32_eq) end, - [c.OP_I32_NE] = function() self:binop(ops.i32_ne) end, - [c.OP_I32_LT_S] = function() self:binop(ops.i32_lt_s) end, - [c.OP_I32_LT_U] = function() self:binop(ops.i32_lt_u) end, - [c.OP_I32_GT_S] = function() self:binop(ops.i32_gt_s) end, - [c.OP_I32_GT_U] = function() self:binop(ops.i32_gt_u) end, - [c.OP_I32_LE_S] = function() self:binop(ops.i32_le_s) end, - [c.OP_I32_LE_U] = function() self:binop(ops.i32_le_u) end, + [c.OP_I32_EQZ] = function() self:unop (ops.i32_eqz) end, + [c.OP_I32_EQ] = function() self:binop(ops.i32_eq) end, + [c.OP_I32_NE] = function() self:binop(ops.i32_ne) end, + [c.OP_I32_LT_S] = function() self:binop(ops.i32_lt_s) end, + [c.OP_I32_LT_U] = function() self:binop(ops.i32_lt_u) end, + [c.OP_I32_GT_S] = function() self:binop(ops.i32_gt_s) end, + [c.OP_I32_GT_U] = function() self:binop(ops.i32_gt_u) end, + [c.OP_I32_LE_S] = function() self:binop(ops.i32_le_s) end, + [c.OP_I32_LE_U] = function() self:binop(ops.i32_le_u) end, -- i64 comparisons - [c.OP_I64_EQZ] = function() self:unop (ops.i64_eqz) end, - [c.OP_I64_EQ] = function() self:binop(ops.i64_eq) end, - [c.OP_I64_NE] = function() self:binop(ops.i64_ne) end, - [c.OP_I64_LT_S] = function() self:binop(ops.i64_lt_s) end, + [c.OP_I64_EQZ] = function() self:unop (ops.i64_eqz) end, + [c.OP_I64_EQ] = function() self:binop(ops.i64_eq) end, + [c.OP_I64_NE] = function() self:binop(ops.i64_ne) end, + [c.OP_I64_LT_S] = function() self:binop(ops.i64_lt_s) end, -- I64_LT_U - [c.OP_I64_GT_S] = function() self:binop(ops.i64_gt_s) end, + [c.OP_I64_GT_S] = function() self:binop(ops.i64_gt_s) end, -- I64_GT_U - [c.OP_I64_LE_S] = function() self:binop(ops.i64_le_s) end, + [c.OP_I64_LE_S] = function() self:binop(ops.i64_le_s) end, -- I64_LE_U - [c.OP_I64_GE_S] = function() self:binop(ops.i64_ge_s) end, + [c.OP_I64_GE_S] = function() self:binop(ops.i64_ge_s) end, -- I64_GE_U -- [float comparisons] -- i32 operations - [c.OP_I32_CLZ] = function() self:unop (ops.i32_clz) end, - [c.OP_I32_CTZ] = function() self:unop (ops.i32_ctz) end, - [c.OP_I32_POPCNT] = function() self:unop (ops.i32_popcnt) end, - [c.OP_I32_ADD] = function() self:binop(ops.i32_add) end, - [c.OP_I32_SUB] = function() self:binop(ops.i32_sub) end, - [c.OP_I32_MUL] = function() self:binop(ops.i32_mul) end, - [c.OP_I32_DIV_S] = function() self:binop(ops.i32_div_s) end, - [c.OP_I32_DIV_U] = function() self:binop(ops.i32_div_u) end, - [c.OP_I32_REM_S] = function() self:binop(ops.i32_rem_s) end, - [c.OP_I32_REM_U] = function() self:binop(ops.i32_rem_u) end, - [c.OP_I32_AND] = function() self:binop(ops.i32_and) end, - [c.OP_I32_OR] = function() self:binop(ops.i32_or) end, - [c.OP_I32_XOR] = function() self:binop(ops.i32_xor) end, - [c.OP_I32_SHL] = function() self:binop(ops.i32_shl) end, - [c.OP_I32_SHR_S] = function() self:binop(ops.i32_shr_s) end, - [c.OP_I32_SHR_U] = function() self:binop(ops.i32_shr_u) end, - [c.OP_I32_ROTL] = function() self:binop(ops.i32_rotl) end, - [c.OP_I32_ROTR] = function() self:binop(ops.i32_rotr) end, + [c.OP_I32_CLZ] = function() self:unop (ops.i32_clz) end, + [c.OP_I32_CTZ] = function() self:unop (ops.i32_ctz) end, + [c.OP_I32_POPCNT] = function() self:unop (ops.i32_popcnt) end, + [c.OP_I32_ADD] = function() self:binop(ops.i32_add) end, + [c.OP_I32_SUB] = function() self:binop(ops.i32_sub) end, + [c.OP_I32_MUL] = function() self:binop(ops.i32_mul) end, + [c.OP_I32_DIV_S] = function() self:binop(ops.i32_div_s) end, + [c.OP_I32_DIV_U] = function() self:binop(ops.i32_div_u) end, + [c.OP_I32_REM_S] = function() self:binop(ops.i32_rem_s) end, + [c.OP_I32_REM_U] = function() self:binop(ops.i32_rem_u) end, + [c.OP_I32_AND] = function() self:binop(ops.i32_and) end, + [c.OP_I32_OR] = function() self:binop(ops.i32_or) end, + [c.OP_I32_XOR] = function() self:binop(ops.i32_xor) end, + [c.OP_I32_SHL] = function() self:binop(ops.i32_shl) end, + [c.OP_I32_SHR_S] = function() self:binop(ops.i32_shr_s) end, + [c.OP_I32_SHR_U] = function() self:binop(ops.i32_shr_u) end, + [c.OP_I32_ROTL] = function() self:binop(ops.i32_rotl) end, + [c.OP_I32_ROTR] = function() self:binop(ops.i32_rotr) end, -- i64 operations - [c.OP_I64_CLZ] = function() self:unop (ops.i64_clz) end, - [c.OP_I64_CTZ] = function() self:unop (ops.i64_ctz) end, - [c.OP_I64_POPCNT] = function() self:unop (ops.i64_popcnt) end, - [c.OP_I64_ADD] = function() self:binop(ops.i64_add) end, - [c.OP_I64_SUB] = function() self:binop(ops.i64_sub) end, - [c.OP_I64_MUL] = function() self:binop(ops.i64_mul) end, - [c.OP_I64_DIV_S] = function() self:binop(ops.i64_div_s) end, + [c.OP_I64_CLZ] = function() self:unop (ops.i64_clz) end, + [c.OP_I64_CTZ] = function() self:unop (ops.i64_ctz) end, + [c.OP_I64_POPCNT] = function() self:unop (ops.i64_popcnt) end, + [c.OP_I64_ADD] = function() self:binop(ops.i64_add) end, + [c.OP_I64_SUB] = function() self:binop(ops.i64_sub) end, + [c.OP_I64_MUL] = function() self:binop(ops.i64_mul) end, + [c.OP_I64_DIV_S] = function() self:binop(ops.i64_div_s) end, -- I64_DIV_U - [c.OP_I64_REM_S] = function() self:binop(ops.i64_rem_s) end, + [c.OP_I64_REM_S] = function() self:binop(ops.i64_rem_s) end, -- I64_REM_U - [c.OP_I64_AND] = function() self:binop(ops.i64_and) end, - [c.OP_I64_OR] = function() self:binop(ops.i64_or) end, - [c.OP_I64_XOR] = function() self:binop(ops.i64_xor) end, - [c.OP_I64_SHL] = function() self:binop(ops.i64_shl) end, - [c.OP_I64_SHR_S] = function() self:binop(ops.i64_shr_s) end, + [c.OP_I64_AND] = function() self:binop(ops.i64_and) end, + [c.OP_I64_OR] = function() self:binop(ops.i64_or) end, + [c.OP_I64_XOR] = function() self:binop(ops.i64_xor) end, + [c.OP_I64_SHL] = function() self:binop(ops.i64_shl) end, + [c.OP_I64_SHR_S] = function() self:binop(ops.i64_shr_s) end, -- I64_SHR_U - [c.OP_I64_ROTL] = function() self:binop(ops.i64_rotl) end, - [c.OP_I64_ROTR] = function() self:binop(ops.i64_rotr) end, + [c.OP_I64_ROTL] = function() self:binop(ops.i64_rotl) end, + [c.OP_I64_ROTR] = function() self:binop(ops.i64_rotr) end, -- [float operations] -- conversions [c.OP_I32_WRAP_I64] = function() self:unop(ops.i32_wrap_i64) end, @@ -413,18 +427,4 @@ function wasmlib.VM:step() opfunc() end -function wasmlib.VM:invoke(funcIndex) - local fr = frame.StackFrame:new(funcIndex) - local f = self.functions[funcIndex] - local sig = self.types[f.typeidx] - for i = 1, #sig.arguments do - fr.locals[#sig.arguments - i] = table.remove(self.stack) - end - table.insert(self.stackFrames, fr) -end - -function wasmlib.VM:ret() - table.remove(self.stackFrames) -end - return wasmlib \ No newline at end of file