diff --git a/wasm/runtime/luajit.lua b/wasm/runtime/luajit.lua index 28c7602..cd46774 100644 --- a/wasm/runtime/luajit.lua +++ b/wasm/runtime/luajit.lua @@ -1,11 +1,11 @@ local module = {} -local bit = require('bit') -local ffi = require('ffi') +local bit = require("bit") +local ffi = require("ffi") -local u32 = ffi.typeof('uint32_t') -local u64 = ffi.typeof('uint64_t') -local i64 = ffi.typeof('int64_t') +local u32 = ffi.typeof("uint32_t") +local u64 = ffi.typeof("uint64_t") +local i64 = ffi.typeof("int64_t") local math_ceil = math.ceil local math_floor = math.floor @@ -28,23 +28,29 @@ do local num_meta = debug.getmetatable(i64) local to_signed = bit.tobit - function add.i32(a, b) return (to_signed(a + b)) end + function add.i32(a, b) + return (to_signed(a + b)) + end add.i64 = num_meta.__add - function sub.i32(a, b) return (to_signed(a - b)) end + function sub.i32(a, b) + return (to_signed(a - b)) + end sub.i64 = num_meta.__sub - function mul.i32(a, b) return (to_signed(a * b)) end + function mul.i32(a, b) + return (to_signed(a * b)) + end mul.i64 = num_meta.__mul function div.i32(lhs, rhs) - assert(rhs ~= 0, 'division by zero') + assert(rhs ~= 0, "division by zero") return (truncate(lhs / rhs)) end function div.u32(lhs, rhs) - assert(rhs ~= 0, 'division by zero') + assert(rhs ~= 0, "division by zero") lhs = to_number(u32(lhs)) rhs = to_number(u32(rhs)) @@ -53,7 +59,7 @@ do end function div.u64(lhs, rhs) - assert(rhs ~= 0, 'division by zero') + assert(rhs ~= 0, "division by zero") return (i64(u64(lhs) / u64(rhs))) end @@ -76,7 +82,9 @@ do for i = 0, 31 do local mask = lj_lshift(1, 31 - i) - if lj_band(num, mask) ~= 0 then return i end + if lj_band(num, mask) ~= 0 then + return i + end end return 32 @@ -86,7 +94,9 @@ do for i = 0, 31 do local mask = lj_lshift(1, i) - if lj_band(num, mask) ~= 0 then return i end + if lj_band(num, mask) ~= 0 then + return i + end end return 32 @@ -114,17 +124,37 @@ do local ge = {} local gt = {} - function ge.u32(lhs, rhs) return u32(lhs) >= u32(rhs) end - function ge.u64(lhs, rhs) return u64(lhs) >= u64(rhs) end + function ge.u32(lhs, rhs) + return u32(lhs) >= u32(rhs) + end - function gt.u32(lhs, rhs) return u32(lhs) > u32(rhs) end - function gt.u64(lhs, rhs) return u64(lhs) > u64(rhs) end + function ge.u64(lhs, rhs) + return u64(lhs) >= u64(rhs) + end - function le.u32(lhs, rhs) return u32(lhs) <= u32(rhs) end - function le.u64(lhs, rhs) return u64(lhs) <= u64(rhs) end + function gt.u32(lhs, rhs) + return u32(lhs) > u32(rhs) + end - function lt.u32(lhs, rhs) return u32(lhs) < u32(rhs) end - function lt.u64(lhs, rhs) return u64(lhs) < u64(rhs) end + function gt.u64(lhs, rhs) + return u64(lhs) > u64(rhs) + end + + function le.u32(lhs, rhs) + return u32(lhs) <= u32(rhs) + end + + function le.u64(lhs, rhs) + return u64(lhs) <= u64(rhs) + end + + function lt.u32(lhs, rhs) + return u32(lhs) < u32(rhs) + end + + function lt.u64(lhs, rhs) + return u64(lhs) < u64(rhs) + end module.le = le module.lt = lt @@ -193,12 +223,12 @@ do -- This would surely be an issue in a multi-thread environment... -- ... thankfully this isn't one. - local RE_INSTANCE = ffi.new [[union { + local RE_INSTANCE = ffi.new([[union { int32_t i32; int64_t i64; float f32; double f64; - }]] + }]]) function wrap.i32_i64(num) RE_INSTANCE.i64 = num @@ -224,15 +254,37 @@ do return RE_INSTANCE.i64 end - function convert.f32_i32(num) return num end - function convert.f32_u32(num) return (to_number(u32(num))) end - function convert.f32_i64(num) return (to_number(num)) end - function convert.f32_u64(num) return (to_number(u64(num))) end + function convert.f32_i32(num) + return num + end - function convert.f64_i32(num) return num end - function convert.f64_u32(num) return (to_number(u32(num))) end - function convert.f64_i64(num) return (to_number(num)) end - function convert.f64_u64(num) return (to_number(u64(num))) end + function convert.f32_u32(num) + return (to_number(u32(num))) + end + + function convert.f32_i64(num) + return (to_number(num)) + end + + function convert.f32_u64(num) + return (to_number(u64(num))) + end + + function convert.f64_i32(num) + return num + end + + function convert.f64_u32(num) + return (to_number(u32(num))) + end + + function convert.f64_i64(num) + return (to_number(num)) + end + + function convert.f64_u64(num) + return (to_number(u64(num))) + end function reinterpret.i32_f32(num) RE_INSTANCE.f32 = num @@ -270,7 +322,7 @@ do local store = {} local memory = {} - ffi.cdef [[ + ffi.cdef([[ union Any { int8_t i8; int16_t i16; @@ -295,10 +347,10 @@ do void *calloc(size_t num, size_t size); void *realloc(void *ptr, size_t size); void free(void *ptr); - ]] + ]]) - local alias_t = ffi.typeof('uint8_t *') - local any_t = ffi.typeof('union Any *') + local alias_t = ffi.typeof("uint8_t *") + local any_t = ffi.typeof("union Any *") local cast = ffi.cast local function by_offset(pointer, offset) @@ -307,60 +359,108 @@ do return cast(any_t, aliased + offset) end - function load.i32_i8(memory, addr) return by_offset(memory.data, addr).i8 end + function load.i32_i8(memory, addr) + return by_offset(memory.data, addr).i8 + end - function load.i32_u8(memory, addr) return by_offset(memory.data, addr).u8 end + function load.i32_u8(memory, addr) + return by_offset(memory.data, addr).u8 + end - function load.i32_i16(memory, addr) return by_offset(memory.data, addr).i16 end + function load.i32_i16(memory, addr) + return by_offset(memory.data, addr).i16 + end - function load.i32_u16(memory, addr) return by_offset(memory.data, addr).u16 end + function load.i32_u16(memory, addr) + return by_offset(memory.data, addr).u16 + end - function load.i32(memory, addr) return by_offset(memory.data, addr).i32 end + function load.i32(memory, addr) + return by_offset(memory.data, addr).i32 + end - function load.i64_i8(memory, addr) return (i64(by_offset(memory.data, addr).i8)) end + function load.i64_i8(memory, addr) + return (i64(by_offset(memory.data, addr).i8)) + end - function load.i64_u8(memory, addr) return (i64(by_offset(memory.data, addr).u8)) end + function load.i64_u8(memory, addr) + return (i64(by_offset(memory.data, addr).u8)) + end - function load.i64_i16(memory, addr) return (i64(by_offset(memory.data, addr).i16)) end + function load.i64_i16(memory, addr) + return (i64(by_offset(memory.data, addr).i16)) + end - function load.i64_u16(memory, addr) return (i64(by_offset(memory.data, addr).u16)) end + function load.i64_u16(memory, addr) + return (i64(by_offset(memory.data, addr).u16)) + end - function load.i64_i32(memory, addr) return (i64(by_offset(memory.data, addr).i32)) end + function load.i64_i32(memory, addr) + return (i64(by_offset(memory.data, addr).i32)) + end - function load.i64_u32(memory, addr) return (i64(by_offset(memory.data, addr).u32)) end + function load.i64_u32(memory, addr) + return (i64(by_offset(memory.data, addr).u32)) + end - function load.i64(memory, addr) return by_offset(memory.data, addr).i64 end + function load.i64(memory, addr) + return by_offset(memory.data, addr).i64 + end - function load.f32(memory, addr) return by_offset(memory.data, addr).f32 end + function load.f32(memory, addr) + return by_offset(memory.data, addr).f32 + end - function load.f64(memory, addr) return by_offset(memory.data, addr).f64 end + function load.f64(memory, addr) + return by_offset(memory.data, addr).f64 + end - function store.i32_n8(memory, addr, value) by_offset(memory.data, addr).i8 = value end + function store.i32_n8(memory, addr, value) + by_offset(memory.data, addr).i8 = value + end - function store.i32_n16(memory, addr, value) by_offset(memory.data, addr).i16 = value end + function store.i32_n16(memory, addr, value) + by_offset(memory.data, addr).i16 = value + end - function store.i32(memory, addr, value) by_offset(memory.data, addr).i32 = value end + function store.i32(memory, addr, value) + by_offset(memory.data, addr).i32 = value + end - function store.i64_n8(memory, addr, value) by_offset(memory.data, addr).i8 = value end + function store.i64_n8(memory, addr, value) + by_offset(memory.data, addr).i8 = value + end - function store.i64_n16(memory, addr, value) by_offset(memory.data, addr).i16 = value end + function store.i64_n16(memory, addr, value) + by_offset(memory.data, addr).i16 = value + end - function store.i64_n32(memory, addr, value) by_offset(memory.data, addr).i32 = value end + function store.i64_n32(memory, addr, value) + by_offset(memory.data, addr).i32 = value + end - function store.i64(memory, addr, value) by_offset(memory.data, addr).i64 = value end + function store.i64(memory, addr, value) + by_offset(memory.data, addr).i64 = value + end - function store.f32(memory, addr, value) by_offset(memory.data, addr).f32 = value end + function store.f32(memory, addr, value) + by_offset(memory.data, addr).f32 = value + end - function store.f64(memory, addr, value) by_offset(memory.data, addr).f64 = value end + function store.f64(memory, addr, value) + by_offset(memory.data, addr).f64 = value + end local WASM_PAGE_SIZE = 65536 - local function finalizer(memory) ffi.C.free(memory.data) end + local function finalizer(memory) + ffi.C.free(memory.data) + end local function grow_unchecked(memory, old, new) memory.data = ffi.C.realloc(memory.data, new) - assert(memory.data ~= nil, 'failed to reallocate') + assert(memory.data ~= nil, "failed to reallocate") ffi.fill(by_offset(memory.data, old), new - old, 0) end @@ -368,14 +468,16 @@ do function memory.new(min, max) local data = ffi.C.calloc(max, WASM_PAGE_SIZE) - assert(data ~= nil, 'failed to allocate') + assert(data ~= nil, "failed to allocate") - local memory = ffi.new('struct Memory', min, max, data) + local memory = ffi.new("struct Memory", min, max, data) return ffi.gc(memory, finalizer) end - function memory.init(memory, addr, data) ffi.copy(by_offset(memory.data, addr), data, #data - 1) end + function memory.init(memory, addr, data) + ffi.copy(by_offset(memory.data, addr), data, #data - 1) + end function memory.grow(memory, num) local old = memory.min diff --git a/wasm/runtime/luau.lua b/wasm/runtime/luau.lua index 6bc4c30..9b8d4b6 100644 --- a/wasm/runtime/luau.lua +++ b/wasm/runtime/luau.lua @@ -1,16 +1,26 @@ local module = {} -local function no_op(x) return x end +local bit32 = bit32 -local function to_u32(x) return bit32.band(x, 0xFFFFFFFF) end +local function no_op(x) + return x +end + +local function to_u32(x) + return bit32.band(x, 0xFFFFFFFF) +end local function to_i32(x) - if x > 0x7FFFFFFF then x = x - 0x100000000 end + if x > 0x7FFFFFFF then + x = x - 0x100000000 + end return x end -local function wrap_i32(x) return to_i32(to_u32(x) % 0x100000000) end +local function wrap_i32(x) + return to_i32(to_u32(x) % 0x100000000) +end local function truncate(num) if num >= 0 then @@ -26,20 +36,26 @@ do local mul = {} local div = {} - function add.i32(a, b) return wrap_i32(a + b) end + function add.i32(a, b) + return wrap_i32(a + b) + end - function sub.i32(a, b) return wrap_i32(a - b) end + function sub.i32(a, b) + return wrap_i32(a - b) + end - function mul.i32(a, b) return wrap_i32(a * b) end + function mul.i32(a, b) + return wrap_i32(a * b) + end function div.i32(lhs, rhs) - assert(rhs ~= 0, 'division by zero') + assert(rhs ~= 0, "division by zero") return truncate(lhs / rhs) end function div.u32(lhs, rhs) - assert(rhs ~= 0, 'division by zero') + assert(rhs ~= 0, "division by zero") lhs = to_u32(lhs) rhs = to_u32(rhs) @@ -94,25 +110,51 @@ do end end - function eq.i32(lhs, rhs) return to_boolean(lhs == rhs) end - function eq.num(lhs, rhs) return to_boolean(lhs == rhs) end + function eq.i32(lhs, rhs) + return to_boolean(lhs == rhs) + end + function eq.num(lhs, rhs) + return to_boolean(lhs == rhs) + end - function eqz.i32(lhs) return to_boolean(lhs == 0) end + function eqz.i32(lhs) + return to_boolean(lhs == 0) + end - function ne.i32(lhs, rhs) return to_boolean(lhs ~= rhs) end - function ne.num(lhs, rhs) return to_boolean(lhs ~= rhs) end + function ne.i32(lhs, rhs) + return to_boolean(lhs ~= rhs) + end + function ne.num(lhs, rhs) + return to_boolean(lhs ~= rhs) + end - function ge.i32(lhs, rhs) return to_boolean(lhs >= rhs) end - function ge.u32(lhs, rhs) return to_boolean(to_u32(lhs) >= to_u32(rhs)) end + function ge.i32(lhs, rhs) + return to_boolean(lhs >= rhs) + end + function ge.u32(lhs, rhs) + return to_boolean(to_u32(lhs) >= to_u32(rhs)) + end - function gt.i32(lhs, rhs) return to_boolean(lhs > rhs) end - function gt.u32(lhs, rhs) return to_boolean(to_u32(lhs) > to_u32(rhs)) end + function gt.i32(lhs, rhs) + return to_boolean(lhs > rhs) + end + function gt.u32(lhs, rhs) + return to_boolean(to_u32(lhs) > to_u32(rhs)) + end - function le.i32(lhs, rhs) return to_boolean(lhs <= rhs) end - function le.u32(lhs, rhs) return to_boolean(to_u32(lhs) <= to_u32(rhs)) end + function le.i32(lhs, rhs) + return to_boolean(lhs <= rhs) + end + function le.u32(lhs, rhs) + return to_boolean(to_u32(lhs) <= to_u32(rhs)) + end - function lt.i32(lhs, rhs) return to_boolean(lhs < rhs) end - function lt.u32(lhs, rhs) return to_boolean(to_u32(lhs) < to_u32(rhs)) end + function lt.i32(lhs, rhs) + return to_boolean(lhs < rhs) + end + function lt.u32(lhs, rhs) + return to_boolean(to_u32(lhs) < to_u32(rhs)) + end module.eqz = eqz module.eq = eq @@ -179,9 +221,13 @@ do extend.i64_i32 = no_op - function convert.f32_i32(num) return num end + function convert.f32_i32(num) + return num + end - function convert.f64_i32(num) return num end + function convert.f64_i32(num) + return num + end module.wrap = wrap module.trunc = trunc @@ -195,9 +241,13 @@ do local store = {} local memory = {} - local function rip_u64(x) return math.floor(x / 0x100000000), x % 0x100000000 end + local function rip_u64(x) + return math.floor(x / 0x100000000), x % 0x100000000 + end - local function merge_u64(hi, lo) return hi * 0x100000000 + lo end + local function merge_u64(hi, lo) + return hi * 0x100000000 + lo + end local function black_mask_byte(value, offset) local mask = bit32.lshift(0xFF, offset * 8) @@ -224,7 +274,9 @@ do function load.i32_i8(memory, addr) local b = load_byte(memory, addr) - if b > 0x7F then b = b - 0x100 end + if b > 0x7F then + b = b - 0x100 + end return b end @@ -275,7 +327,9 @@ do store.i32(memory, addr + 4, hi) end - function memory.new(min, max) return {min = min, max = max, data = {}} end + function memory.new(min, max) + return { min = min, max = max, data = {} } + end function memory.init(memory, offset, data) local store_i8 = module.store.i32_n8 @@ -285,7 +339,7 @@ do local rem = len % 4 for i = 1, len - rem, 4 do - local v = string.unpack('