quick and dirty pure lua webassembly interpreter
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

basic i64 ops

+407 -183
+1
.gitignore
··· 1 + test.lua
+187 -183
constants.lua
··· 1 - opcodes = { 1 + local constants = {} 2 + 3 + constants.opcodes = { 2 4 -- Control 3 - OP_UNREACHABLE = 0x00 4 - OP_NOP = 0x01 5 - OP_BLOCK = 0x02 6 - OP_LOOP = 0x03 7 - OP_IF = 0x04 8 - OP_ELSE = 0x05 9 - OP_END = 0x0B 10 - OP_BR = 0x0C 11 - OP_BR_IF = 0x0D 12 - OP_BR_TABLE = 0x0E 13 - OP_RETURN = 0x0F 14 - OP_CALL = 0x10 15 - OP_CALL_INDIRECT = 0x11 5 + OP_UNREACHABLE = 0x00, 6 + OP_NOP = 0x01, 7 + OP_BLOCK = 0x02, 8 + OP_LOOP = 0x03, 9 + OP_IF = 0x04, 10 + OP_ELSE = 0x05, 11 + OP_END = 0x0B, 12 + OP_BR = 0x0C, 13 + OP_BR_IF = 0x0D, 14 + OP_BR_TABLE = 0x0E, 15 + OP_RETURN = 0x0F, 16 + OP_CALL = 0x10, 17 + OP_CALL_INDIRECT = 0x11, 16 18 -- Parametric 17 - OP_DROP = 0x1A 18 - OP_SELECT = 0x1B 19 + OP_DROP = 0x1A, 20 + OP_SELECT = 0x1B, 19 21 -- Variable 20 - OP_LOCAL_GET = 0x20 21 - OP_LOCAL_SET = 0x21 22 - OP_LOCAL_TEE = 0x22 23 - OP_GLOBAL_GET = 0x23 24 - OP_GLOBAL_SET = 0x24 22 + OP_LOCAL_GET = 0x20, 23 + OP_LOCAL_SET = 0x21, 24 + OP_LOCAL_TEE = 0x22, 25 + OP_GLOBAL_GET = 0x23, 26 + OP_GLOBAL_SET = 0x24, 25 27 -- Memory 26 - OP_I32_LOAD = 0x28 27 - OP_I64_LOAD = 0x29 28 - OP_F32_LOAD = 0x2A 29 - OP_F64_LOAD = 0x2B 30 - OP_I32_LOAD8_S = 0x2C 31 - OP_I32_LOAD8_U = 0x2D 32 - OP_I32_LOAD16_S = 0x2E 33 - OP_I32_LOAD16_U = 0x2F 34 - OP_I64_LOAD8_S = 0x30 35 - OP_I64_LOAD8_U = 0x31 36 - OP_I64_LOAD16_S = 0x32 37 - OP_I64_LOAD16_U = 0x33 38 - OP_I64_LOAD32_S = 0x34 39 - OP_I64_LOAD32_U = 0x35 40 - OP_I32_STORE = 0x36 41 - OP_I64_STORE = 0x37 42 - OP_F32_STORE = 0x38 43 - OP_F64_STORE = 0x39 44 - OP_I32_STORE8 = 0x3A 45 - OP_I32_STORE16 = 0x3B 46 - OP_I64_STORE8 = 0x3C 47 - OP_I64_STORE16 = 0x3D 48 - OP_I64_STORE32 = 0x3E 49 - OP_MEMORY_SIZE = 0x3F 50 - OP_MEMORY_GROW = 0x40 28 + OP_I32_LOAD = 0x28, 29 + OP_I64_LOAD = 0x29, 30 + OP_F32_LOAD = 0x2A, 31 + OP_F64_LOAD = 0x2B, 32 + OP_I32_LOAD8_S = 0x2C, 33 + OP_I32_LOAD8_U = 0x2D, 34 + OP_I32_LOAD16_S = 0x2E, 35 + OP_I32_LOAD16_U = 0x2F, 36 + OP_I64_LOAD8_S = 0x30, 37 + OP_I64_LOAD8_U = 0x31, 38 + OP_I64_LOAD16_S = 0x32, 39 + OP_I64_LOAD16_U = 0x33, 40 + OP_I64_LOAD32_S = 0x34, 41 + OP_I64_LOAD32_U = 0x35, 42 + OP_I32_STORE = 0x36, 43 + OP_I64_STORE = 0x37, 44 + OP_F32_STORE = 0x38, 45 + OP_F64_STORE = 0x39, 46 + OP_I32_STORE8 = 0x3A, 47 + OP_I32_STORE16 = 0x3B, 48 + OP_I64_STORE8 = 0x3C, 49 + OP_I64_STORE16 = 0x3D, 50 + OP_I64_STORE32 = 0x3E, 51 + OP_MEMORY_SIZE = 0x3F, 52 + OP_MEMORY_GROW = 0x40, 51 53 -- Numeric Constants 52 - OP_I32_CONST = 0x41 53 - OP_I64_CONST = 0x42 54 - OP_F32_CONST = 0x43 55 - OP_F64_CONST = 0x44 54 + OP_I32_CONST = 0x41, 55 + OP_I64_CONST = 0x42, 56 + OP_F32_CONST = 0x43, 57 + OP_F64_CONST = 0x44, 56 58 -- Numeric Operations 57 - --- i32 comparisons 58 - OP_I32_EQZ = 0x45 59 - OP_I32_EQ = 0x46 60 - OP_I32_NE = 0x47 61 - OP_I32_LT_S = 0x48 62 - OP_I32_LT_U = 0x49 63 - OP_I32_GT_S = 0x50 64 - OP_I32_GT_U = 0x51 65 - OP_I32_LE_S = 0x52 66 - OP_I32_LE_U = 0x53 67 - OP_I32_GE_S = 0x54 68 - OP_I32_GE_U = 0x55 69 - --- i64 comparisons 70 - OP_I64_EQZ = 0x50 71 - OP_I64_EQ = 0x51 72 - OP_I64_NE = 0x52 73 - OP_I64_LT_S = 0x53 74 - OP_I64_LT_U = 0x54 75 - OP_I64_GT_S = 0x55 76 - OP_I64_GT_U = 0x56 77 - OP_I64_LE_S = 0x57 78 - OP_I64_LE_U = 0x58 79 - OP_I64_GE_S = 0x59 80 - OP_I64_GE_U = 0x5A 81 - --- f32 comparisons 82 - OP_F32_EQ = 0x5B 83 - OP_F32_NE = 0x5C 84 - OP_F32_LT = 0x5D 85 - OP_F32_GT = 0x5E 86 - OP_F32_LE = 0x5F 87 - OP_F32_GE = 0x60 88 - --- f64 comparisons 89 - OP_F64_EQ = 0x61 90 - OP_F64_NE = 0x62 91 - OP_F64_LT = 0x63 92 - OP_F64_GT = 0x64 93 - OP_F64_LE = 0x65 94 - OP_F64_GE = 0x66 95 - --- i32 operations 96 - OP_I32_CLZ = 0x67 97 - OP_I32_CTZ = 0x68 98 - OP_I32_POPCNT = 0x69 99 - OP_I32_ADD = 0x6A 100 - OP_I32_SUB = 0x6B 101 - OP_I32_MUL = 0x6C 102 - OP_I32_DIV_S = 0x6D 103 - OP_I32_DIV_U = 0x6E 104 - OP_I32_REM_S = 0x6F 105 - OP_I32_REM_U = 0x70 106 - OP_I32_AND = 0x71 107 - OP_I32_OR = 0x72 108 - OP_I32_XOR = 0x73 109 - OP_I32_SHL = 0x74 110 - OP_I32_SHR_S = 0x75 111 - OP_I32_SHR_U = 0x76 112 - OP_I32_ROTL = 0x77 113 - OP_I32_ROTR = 0x78 114 - --- i64 operations 115 - OP_I64_CLZ = 0x79 116 - OP_I64_CTZ = 0x7A 117 - OP_I64_POPCNT = 0x7B 118 - OP_I64_ADD = 0x7C 119 - OP_I64_SUB = 0x7D 120 - OP_I64_MUL = 0x7E 121 - OP_I64_DIV_S = 0x7F 122 - OP_I64_DIV_U = 0x80 123 - OP_I64_REM_S = 0x81 124 - OP_I64_REM_U = 0x82 125 - OP_I64_AND = 0x83 126 - OP_I64_OR = 0x84 127 - OP_I64_XOR = 0x85 128 - OP_I64_SHL = 0x86 129 - OP_I64_SHR_S = 0x87 130 - OP_I64_SHR_U = 0x88 131 - OP_I64_ROTL = 0x89 132 - OP_I64_ROTR = 0x8A 133 - --- f32 operations 134 - OP_F32_ABS = 0x8B 135 - OP_F32_NEG = 0x8C 136 - OP_F32_CEIL = 0x8D 137 - OP_F32_FLOOR = 0x8E 138 - OP_F32_TRUNC = 0x8F 139 - OP_F32_NEAREST = 0x90 140 - OP_F32_SQRT = 0x91 141 - OP_F32_ADD = 0x92 142 - OP_F32_SUB = 0x93 143 - OP_F32_MUL = 0x94 144 - OP_F32_DIV = 0x95 145 - OP_F32_MIN = 0x96 146 - OP_F32_MAX = 0x97 147 - OP_F32_COPYSIGN = 0x98 148 - --- f64 operations 149 - OP_F64_ABS = 0x99 150 - OP_F64_NEG = 0x9A 151 - OP_F64_CEIL = 0x9B 152 - OP_F64_FLOOR = 0x9C 153 - OP_F64_TRUNC = 0x9D 154 - OP_F64_NEAREST = 0x9E 155 - OP_F64_SQRT = 0x9F 156 - OP_F64_ADD = 0xA0 157 - OP_F64_SUB = 0xA1 158 - OP_F64_MUL = 0xA2 159 - OP_F64_DIV = 0xA3 160 - OP_F64_MIN = 0xA4 161 - OP_F64_MAX = 0xA5 162 - OP_F64_COPYSIGN = 0xA6 163 - --- conversions 164 - OP_I32_WRAP_I64 = 0xA7 165 - OP_I32_TRUNC_F32_S = 0xA8 166 - OP_I32_TRUNC_F32_U = 0xA9 167 - OP_I32_TRUNC_F64_S = 0xAA 168 - OP_I32_TRUNC_F64_U = 0xAB 169 - OP_I64_EXTEND_I32_S = 0xAC 170 - OP_I64_EXTEND_I32_U = 0xAD 171 - OP_I64_TRUNC_F32_S = 0xAE 172 - OP_I64_TRUNC_F32_U = 0xAF 173 - OP_I64_TRUNC_F64_S = 0xB0 174 - OP_I64_TRUNC_F64_U = 0xB1 175 - OP_F32_CONVERT_I32_S = 0xB2 176 - OP_F32_CONVERT_I32_U = 0xB3 177 - OP_F32_CONVERT_I64_S = 0xB4 178 - OP_F32_CONVERT_I64_U = 0xB5 179 - OP_F32_DEMOTE_F64 = 0xB6 180 - OP_F64_CONVERT_I32_S = 0xB7 181 - OP_F64_CONVERT_I32_U = 0xB8 182 - OP_F64_CONVERT_I64_S = 0xB9 183 - OP_F64_CONVERT_I64_U = 0xBA 184 - OP_F64_PROMOTE_F32 = 0xBB 185 - OP_I32_REINTERPRET_F32 = 0xBC 186 - OP_I64_REINTERPRET_F64 = 0xBD 187 - OP_F32_REINTERPRET_I32 = 0xBE 188 - OP_F64_REINTERPRET_I64 = 0xBF 189 - } 59 + -- i32 comparisons 60 + OP_I32_EQZ = 0x45, 61 + OP_I32_EQ = 0x46, 62 + OP_I32_NE = 0x47, 63 + OP_I32_LT_S = 0x48, 64 + OP_I32_LT_U = 0x49, 65 + OP_I32_GT_S = 0x50, 66 + OP_I32_GT_U = 0x51, 67 + OP_I32_LE_S = 0x52, 68 + OP_I32_LE_U = 0x53, 69 + OP_I32_GE_S = 0x54, 70 + OP_I32_GE_U = 0x55, 71 + -- i64 comparisons 72 + OP_I64_EQZ = 0x50, 73 + OP_I64_EQ = 0x51, 74 + OP_I64_NE = 0x52, 75 + OP_I64_LT_S = 0x53, 76 + OP_I64_LT_U = 0x54, 77 + OP_I64_GT_S = 0x55, 78 + OP_I64_GT_U = 0x56, 79 + OP_I64_LE_S = 0x57, 80 + OP_I64_LE_U = 0x58, 81 + OP_I64_GE_S = 0x59, 82 + OP_I64_GE_U = 0x5A, 83 + -- f32 comparisons 84 + OP_F32_EQ = 0x5B, 85 + OP_F32_NE = 0x5C, 86 + OP_F32_LT = 0x5D, 87 + OP_F32_GT = 0x5E, 88 + OP_F32_LE = 0x5F, 89 + OP_F32_GE = 0x60, 90 + -- f64 comparisons 91 + OP_F64_EQ = 0x61, 92 + OP_F64_NE = 0x62, 93 + OP_F64_LT = 0x63, 94 + OP_F64_GT = 0x64, 95 + OP_F64_LE = 0x65, 96 + OP_F64_GE = 0x66, 97 + -- i32 operations 98 + OP_I32_CLZ = 0x67, 99 + OP_I32_CTZ = 0x68, 100 + OP_I32_POPCNT = 0x69, 101 + OP_I32_ADD = 0x6A, 102 + OP_I32_SUB = 0x6B, 103 + OP_I32_MUL = 0x6C, 104 + OP_I32_DIV_S = 0x6D, 105 + OP_I32_DIV_U = 0x6E, 106 + OP_I32_REM_S = 0x6F, 107 + OP_I32_REM_U = 0x70, 108 + OP_I32_AND = 0x71, 109 + OP_I32_OR = 0x72, 110 + OP_I32_XOR = 0x73, 111 + OP_I32_SHL = 0x74, 112 + OP_I32_SHR_S = 0x75, 113 + OP_I32_SHR_U = 0x76, 114 + OP_I32_ROTL = 0x77, 115 + OP_I32_ROTR = 0x78, 116 + -- i64 operations 117 + OP_I64_CLZ = 0x79, 118 + OP_I64_CTZ = 0x7A, 119 + OP_I64_POPCNT = 0x7B, 120 + OP_I64_ADD = 0x7C, 121 + OP_I64_SUB = 0x7D, 122 + OP_I64_MUL = 0x7E, 123 + OP_I64_DIV_S = 0x7F, 124 + OP_I64_DIV_U = 0x80, 125 + OP_I64_REM_S = 0x81, 126 + OP_I64_REM_U = 0x82, 127 + OP_I64_AND = 0x83, 128 + OP_I64_OR = 0x84, 129 + OP_I64_XOR = 0x85, 130 + OP_I64_SHL = 0x86, 131 + OP_I64_SHR_S = 0x87, 132 + OP_I64_SHR_U = 0x88, 133 + OP_I64_ROTL = 0x89, 134 + OP_I64_ROTR = 0x8A, 135 + -- f32 operations 136 + OP_F32_ABS = 0x8B, 137 + OP_F32_NEG = 0x8C, 138 + OP_F32_CEIL = 0x8D, 139 + OP_F32_FLOOR = 0x8E, 140 + OP_F32_TRUNC = 0x8F, 141 + OP_F32_NEAREST = 0x90, 142 + OP_F32_SQRT = 0x91, 143 + OP_F32_ADD = 0x92, 144 + OP_F32_SUB = 0x93, 145 + OP_F32_MUL = 0x94, 146 + OP_F32_DIV = 0x95, 147 + OP_F32_MIN = 0x96, 148 + OP_F32_MAX = 0x97, 149 + OP_F32_COPYSIGN = 0x98, 150 + -- f64 operations 151 + OP_F64_ABS = 0x99, 152 + OP_F64_NEG = 0x9A, 153 + OP_F64_CEIL = 0x9B, 154 + OP_F64_FLOOR = 0x9C, 155 + OP_F64_TRUNC = 0x9D, 156 + OP_F64_NEAREST = 0x9E, 157 + OP_F64_SQRT = 0x9F, 158 + OP_F64_ADD = 0xA0, 159 + OP_F64_SUB = 0xA1, 160 + OP_F64_MUL = 0xA2, 161 + OP_F64_DIV = 0xA3, 162 + OP_F64_MIN = 0xA4, 163 + OP_F64_MAX = 0xA5, 164 + OP_F64_COPYSIGN = 0xA6, 165 + -- conversions 166 + OP_I32_WRAP_I64 = 0xA7, 167 + OP_I32_TRUNC_F32_S = 0xA8, 168 + OP_I32_TRUNC_F32_U = 0xA9, 169 + OP_I32_TRUNC_F64_S = 0xAA, 170 + OP_I32_TRUNC_F64_U = 0xAB, 171 + OP_I64_EXTEND_I32_S = 0xAC, 172 + OP_I64_EXTEND_I32_U = 0xAD, 173 + OP_I64_TRUNC_F32_S = 0xAE, 174 + OP_I64_TRUNC_F32_U = 0xAF, 175 + OP_I64_TRUNC_F64_S = 0xB0, 176 + OP_I64_TRUNC_F64_U = 0xB1, 177 + OP_F32_CONVERT_I32_S = 0xB2, 178 + OP_F32_CONVERT_I32_U = 0xB3, 179 + OP_F32_CONVERT_I64_S = 0xB4, 180 + OP_F32_CONVERT_I64_U = 0xB5, 181 + OP_F32_DEMOTE_F64 = 0xB6, 182 + OP_F64_CONVERT_I32_S = 0xB7, 183 + OP_F64_CONVERT_I32_U = 0xB8, 184 + OP_F64_CONVERT_I64_S = 0xB9, 185 + OP_F64_CONVERT_I64_U = 0xBA, 186 + OP_F64_PROMOTE_F32 = 0xBB, 187 + OP_I32_REINTERPRET_F32 = 0xBC, 188 + OP_I64_REINTERPRET_F64 = 0xBD, 189 + OP_F32_REINTERPRET_I32 = 0xBE, 190 + OP_F64_REINTERPRET_I64 = 0xBF, 191 + } 192 + 193 + return constants
+157
ops.lua
··· 1 + local ops = {} 2 + 3 + function ops.i64_eqz(a) 4 + return (a == 0) and 1 or 0 5 + end 6 + 7 + function ops.i64_eq(a, b) 8 + return (a == b) and 1 or 0 9 + end 10 + 11 + function ops.i64_ne(a, b) 12 + return (a ~= b) and 1 or 0 13 + end 14 + 15 + function ops.i64_lt_s(a, b) 16 + return (a < b) and 1 or 0 17 + end 18 + 19 + function ops.i64_gt_s(a, b) 20 + return (a > b) and 1 or 0 21 + end 22 + 23 + function ops.i64_le_s(a, b) 24 + return (a <= b) and 1 or 0 25 + end 26 + 27 + function ops.i64_ge_s(a, b) 28 + return (a >= b) and 1 or 0 29 + end 30 + 31 + function ops.i64_clz(a) 32 + if a == 0 then 33 + return 64 34 + end 35 + 36 + local n = 0 37 + if (a & 0xFFFFFFFF00000000) == 0 then 38 + n = n + 32 39 + a = a << 32 40 + end 41 + if (a & 0xFFFF000000000000) == 0 then 42 + n = n + 16 43 + a = a << 16 44 + end 45 + if (a & 0xFF00000000000000) == 0 then 46 + n = n + 8 47 + a = a << 8 48 + end 49 + if (a & 0xF000000000000000) == 0 then 50 + n = n + 4 51 + a = a << 4 52 + end 53 + if (a & 0xC000000000000000) == 0 then 54 + n = n + 2 55 + a = a << 2 56 + end 57 + if (a & 0x8000000000000000) == 0 then 58 + n = n + 1 59 + end 60 + 61 + return n 62 + end 63 + 64 + function ops.i64_ctz(a) 65 + if a == 0 then 66 + return 64 67 + end 68 + 69 + local n = 0 70 + if (a & 0x00000000FFFFFFFF) == 0 then 71 + n = n + 32 72 + a = a >> 32 73 + end 74 + if (a & 0x000000000000FFFF) == 0 then 75 + n = n + 16 76 + a = a >> 16 77 + end 78 + if (a & 0x00000000000000FF) == 0 then 79 + n = n + 8 80 + a = a >> 8 81 + end 82 + if (a & 0x000000000000000F) == 0 then 83 + n = n + 4 84 + a = a >> 4 85 + end 86 + if (a & 0x0000000000000003) == 0 then 87 + n = n + 2 88 + a = a >> 2 89 + end 90 + if (a & 0x0000000000000001) == 0 then 91 + n = n + 1 92 + end 93 + return n 94 + end 95 + 96 + function ops.i64_popcnt(a) 97 + local n = 0 98 + for _ = 1, 64 do 99 + if (a & 1) == 1 then 100 + n = n + 1 101 + end 102 + a = a >> 1 103 + end 104 + return n 105 + end 106 + 107 + function ops.i64_add(a, b) 108 + return a + b 109 + end 110 + 111 + function ops.i64_sub(a, b) 112 + return a - b 113 + end 114 + 115 + function ops.i64_mul(a, b) 116 + return a * b 117 + end 118 + 119 + function ops.i64_div_s(a, b) 120 + return a / b 121 + end 122 + 123 + function ops.i64_rem_s(a, b) 124 + return a % b 125 + end 126 + 127 + function ops.i64_and(a, b) 128 + return a & b 129 + end 130 + 131 + function ops.i64_or(a, b) 132 + return a | b 133 + end 134 + 135 + function ops.i64_xor(a, b) 136 + return a ~ b 137 + end 138 + 139 + function ops.i64_shl(a, b) 140 + return a >> b 141 + end 142 + 143 + function ops.i64_shr_s(a, b) 144 + return a << b 145 + end 146 + 147 + function ops.i64_rotl(a, b) 148 + local c = b % 64 149 + return (a << c) | (a >> (64 - c)) 150 + end 151 + 152 + function ops.i64_rotr(a, b) 153 + local c = b % 64 154 + return (a >> c) | (a << (64 - c)) 155 + end 156 + 157 + return ops
+62
wasmlib.lua
··· 1 + local wasmlib = {} 2 + 3 + local constants = require("constants") 4 + local ops = require("ops") 5 + 6 + wasmlib.VM = { 7 + stack = {}, 8 + } 9 + 10 + function wasmlib.VM:new() 11 + local vm = {} 12 + setmetatable(vm, {__index = self}) 13 + return vm 14 + end 15 + 16 + function wasmlib.VM:binop(f) 17 + local a = table.remove(self.stack) 18 + local b = table.remove(self.stack) 19 + table.insert(self.stack, f(a, b)) 20 + end 21 + 22 + function wasmlib.VM:unop(f) 23 + local a = table.remove(self.stack) 24 + table.insert(self.stack, f(a)) 25 + end 26 + 27 + function wasmlib.VM:doOperation(opcode) 28 + local c = constants.opcodes 29 + local optable = { 30 + [c.OP_NOP] = function() end, 31 + [c.OP_I64_EQZ] = function() self:unop (ops.i64_eqz) end, 32 + [c.OP_I64_EQ] = function() self:binop(ops.i64_eq) end, 33 + [c.OP_I64_NE] = function() self:binop(ops.i64_ne) end, 34 + [c.OP_I64_LT_S] = function() self:binop(ops.i64_lt_s) end, 35 + [c.OP_I64_GT_S] = function() self:binop(ops.i64_gt_s) end, 36 + [c.OP_I64_LE_S] = function() self:binop(ops.i64_le_s) end, 37 + [c.OP_I64_GE_S] = function() self:binop(ops.i64_ge_s) end, 38 + [c.OP_I64_CLZ] = function() self:unop (ops.i64_clz) end, 39 + [c.OP_I64_CTZ] = function() self:unop (ops.i64_ctz) end, 40 + [c.OP_I64_POPCNT] = function() self:unop (ops.i64_popcnt) end, 41 + [c.OP_I64_ADD] = function() self:binop(ops.i64_add) end, 42 + [c.OP_I64_SUB] = function() self:binop(ops.i64_sub) end, 43 + [c.OP_I64_MUL] = function() self:binop(ops.i64_mul) end, 44 + [c.OP_I64_DIV_S] = function() self:binop(ops.i64_div_s) end, 45 + [c.OP_I64_REM_S] = function() self:binop(ops.i64_rem_s) end, 46 + [c.OP_I64_AND] = function() self:binop(ops.i64_and) end, 47 + [c.OP_I64_OR] = function() self:binop(ops.i64_or) end, 48 + [c.OP_I64_XOR] = function() self:binop(ops.i64_xor) end, 49 + [c.OP_I64_SHL] = function() self:binop(ops.i64_shl) end, 50 + [c.OP_I64_SHR_S] = function() self:binop(ops.i64_shr_s) end, 51 + [c.OP_I64_ROTL] = function() self:binop(ops.i64_rotl) end, 52 + [c.OP_I64_ROTR] = function() self:binop(ops.i64_rotr) end, 53 + } 54 + 55 + local opfunc = optable[opcode] 56 + if opfunc == nil then 57 + error("unimplemented") 58 + end 59 + opfunc() 60 + end 61 + 62 + return wasmlib