Add buffer skeleton
This commit is contained in:
parent
b18365a7e4
commit
49d2456fca
@ -2,7 +2,6 @@ local module = {}
|
|||||||
|
|
||||||
local to_u32 = bit32.band
|
local to_u32 = bit32.band
|
||||||
|
|
||||||
local bit_or = bit32.bor
|
|
||||||
local bit_and = bit32.band
|
local bit_and = bit32.band
|
||||||
local bit_lshift = bit32.lshift
|
local bit_lshift = bit32.lshift
|
||||||
local bit_rshift = bit32.rshift
|
local bit_rshift = bit32.rshift
|
||||||
@ -139,14 +138,18 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function copysign.f32(lhs, rhs)
|
local CP_INSTANCE = buffer.create(8)
|
||||||
local packed = string_pack("<d", rhs)
|
|
||||||
local sign = string_byte(packed, 8)
|
|
||||||
|
|
||||||
if sign >= 0x80 then
|
local buffer_write_f64 = buffer.writef64
|
||||||
return -math_abs(lhs)
|
local buffer_read_i8 = buffer.readi8
|
||||||
|
|
||||||
|
function copysign.f32(lhs, rhs)
|
||||||
|
buffer_write_f64(CP_INSTANCE, 0, rhs)
|
||||||
|
|
||||||
|
if buffer_read_i8(CP_INSTANCE, 7) >= 0 then
|
||||||
|
return (math_abs(lhs))
|
||||||
else
|
else
|
||||||
return math_abs(lhs)
|
return -math_abs(lhs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -154,10 +157,10 @@ do
|
|||||||
local result = math_round(num)
|
local result = math_round(num)
|
||||||
|
|
||||||
if (math_abs(num) + 0.5) % 2 == 1 then
|
if (math_abs(num) + 0.5) % 2 == 1 then
|
||||||
result = result - math_sign(result)
|
return result - math_sign(result)
|
||||||
|
else
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
neg.f64 = neg.f32
|
neg.f64 = neg.f32
|
||||||
@ -376,9 +379,6 @@ do
|
|||||||
local math_floor = math.floor
|
local math_floor = math.floor
|
||||||
local math_clamp = math.clamp
|
local math_clamp = math.clamp
|
||||||
|
|
||||||
local string_pack = string.pack
|
|
||||||
local string_unpack = string.unpack
|
|
||||||
|
|
||||||
local NUM_ZERO = Integer.ZERO
|
local NUM_ZERO = Integer.ZERO
|
||||||
local NUM_MIN_I64 = num_from_u32(0, 0x80000000)
|
local NUM_MIN_I64 = num_from_u32(0, 0x80000000)
|
||||||
local NUM_MAX_I64 = num_from_u32(0xFFFFFFFF, 0x7FFFFFFF)
|
local NUM_MAX_I64 = num_from_u32(0xFFFFFFFF, 0x7FFFFFFF)
|
||||||
@ -576,30 +576,44 @@ do
|
|||||||
|
|
||||||
promote.f64_f32 = no_op
|
promote.f64_f32 = no_op
|
||||||
|
|
||||||
function reinterpret.i32_f32(num)
|
local RE_INSTANCE = buffer.create(8)
|
||||||
local packed = string_pack("f", num)
|
|
||||||
|
|
||||||
return string_unpack("I4", packed)
|
local buffer_read_f32 = buffer.readf32
|
||||||
|
local buffer_read_f64 = buffer.readf64
|
||||||
|
local buffer_read_u32 = buffer.readu32
|
||||||
|
|
||||||
|
local buffer_write_f32 = buffer.writef32
|
||||||
|
local buffer_write_f64 = buffer.writef64
|
||||||
|
local buffer_write_u32 = buffer.writeu32
|
||||||
|
|
||||||
|
function reinterpret.i32_f32(num)
|
||||||
|
buffer_write_f32(RE_INSTANCE, 0, num)
|
||||||
|
|
||||||
|
return buffer_read_u32(RE_INSTANCE, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function reinterpret.i64_f64(num)
|
function reinterpret.i64_f64(num)
|
||||||
local packed = string_pack("d", num)
|
buffer_write_f64(RE_INSTANCE, 0, num)
|
||||||
local data_1, data_2 = string_unpack("I4I4", packed)
|
|
||||||
|
local data_1 = buffer_read_u32(RE_INSTANCE, 0)
|
||||||
|
local data_2 = buffer_read_u32(RE_INSTANCE, 4)
|
||||||
|
|
||||||
return num_from_u32(data_1, data_2)
|
return num_from_u32(data_1, data_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
function reinterpret.f32_i32(num)
|
function reinterpret.f32_i32(num)
|
||||||
local packed = string_pack("I4", num)
|
buffer_write_u32(RE_INSTANCE, 0, num)
|
||||||
|
|
||||||
return string_unpack("f", packed)
|
return buffer_read_f32(RE_INSTANCE, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function reinterpret.f64_i64(num)
|
function reinterpret.f64_i64(num)
|
||||||
local data_1, data_2 = num_into_u32(num)
|
local data_1, data_2 = num_into_u32(num)
|
||||||
local packed = string_pack("I4I4", data_1, data_2)
|
|
||||||
|
|
||||||
return string_unpack("d", packed)
|
buffer_write_u32(RE_INSTANCE, 0, data_1)
|
||||||
|
buffer_write_u32(RE_INSTANCE, 4, data_2)
|
||||||
|
|
||||||
|
return buffer_read_f64(RE_INSTANCE, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
module.wrap = wrap
|
module.wrap = wrap
|
||||||
@ -617,357 +631,214 @@ do
|
|||||||
local store = {}
|
local store = {}
|
||||||
local allocator = {}
|
local allocator = {}
|
||||||
|
|
||||||
local bit_extract = bit32.extract
|
local string_sub = string.sub
|
||||||
local bit_replace = bit32.replace
|
|
||||||
|
|
||||||
local math_floor = math.floor
|
local buffer_create = buffer.create
|
||||||
|
local buffer_to_string = buffer.tostring
|
||||||
|
local buffer_from_string = buffer.fromstring
|
||||||
|
|
||||||
local string_byte = string.byte
|
local buffer_len = buffer.len
|
||||||
local string_char = string.char
|
local buffer_copy = buffer.copy
|
||||||
local string_unpack = string.unpack
|
local buffer_fill = buffer.fill
|
||||||
|
|
||||||
local reinterpret_f32_i32 = module.reinterpret.f32_i32
|
local buffer_read_i8 = buffer.readi8
|
||||||
local reinterpret_f64_i64 = module.reinterpret.f64_i64
|
local buffer_read_u8 = buffer.readu8
|
||||||
local reinterpret_i32_f32 = module.reinterpret.i32_f32
|
local buffer_read_i16 = buffer.readi16
|
||||||
local reinterpret_i64_f64 = module.reinterpret.i64_f64
|
local buffer_read_u16 = buffer.readu16
|
||||||
|
local buffer_read_i32 = buffer.readi32
|
||||||
|
local buffer_read_u32 = buffer.readu32
|
||||||
|
local buffer_read_f32 = buffer.readf32
|
||||||
|
local buffer_read_f64 = buffer.readf64
|
||||||
|
|
||||||
local function load_byte(data, addr)
|
local buffer_write_u8 = buffer.writeu8
|
||||||
local value = data[math_floor(addr / 4)] or 0
|
local buffer_write_u16 = buffer.writeu16
|
||||||
|
local buffer_write_u32 = buffer.writeu32
|
||||||
return bit_extract(value, addr % 4 * 8, 8)
|
local buffer_write_f32 = buffer.writef32
|
||||||
end
|
local buffer_write_f64 = buffer.writef64
|
||||||
|
|
||||||
local function store_byte(data, addr, value)
|
|
||||||
local adjust = math_floor(addr / 4)
|
|
||||||
|
|
||||||
data[adjust] = bit_replace(data[adjust] or 0, value, addr % 4 * 8, 8)
|
|
||||||
end
|
|
||||||
|
|
||||||
function load.i32_i8(memory, addr)
|
function load.i32_i8(memory, addr)
|
||||||
local temp = load_byte(memory.data, addr)
|
local value = buffer_read_i8(memory.data, addr)
|
||||||
|
|
||||||
if temp >= 0x80 then
|
if value >= 0 then
|
||||||
return to_u32(temp - 0x100)
|
return value
|
||||||
else
|
else
|
||||||
return temp
|
return value + 0x100000000
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i32_u8(memory, addr)
|
function load.i32_u8(memory, addr)
|
||||||
return load_byte(memory.data, addr)
|
return buffer_read_u8(memory.data, addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i32_i16(memory, addr)
|
function load.i32_i16(memory, addr)
|
||||||
local data = memory.data
|
local value = buffer_read_i16(memory.data, addr)
|
||||||
local temp
|
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
if value >= 0 then
|
||||||
temp = bit_and(data[addr / 4] or 0, 0xFFFF)
|
return value
|
||||||
else
|
else
|
||||||
local b1 = load_byte(data, addr)
|
return value + 0x100000000
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
|
|
||||||
temp = bit_or(b1, b2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if temp >= 0x8000 then
|
|
||||||
return to_u32(temp - 0x10000)
|
|
||||||
else
|
|
||||||
return temp
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i32_u16(memory, addr)
|
function load.i32_u16(memory, addr)
|
||||||
local data = memory.data
|
return buffer_read_u16(memory.data, addr)
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
|
||||||
return bit_and(data[addr / 4] or 0, 0xFFFF)
|
|
||||||
else
|
|
||||||
local b1 = load_byte(data, addr)
|
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
|
|
||||||
return bit_or(b1, b2)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i32(memory, addr)
|
function load.i32(memory, addr)
|
||||||
local data = memory.data
|
return buffer_read_u32(memory.data, addr)
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
|
||||||
-- aligned read
|
|
||||||
return data[addr / 4] or 0
|
|
||||||
else
|
|
||||||
-- unaligned read
|
|
||||||
local b1 = load_byte(data, addr)
|
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
local b3 = bit_lshift(load_byte(data, addr + 2), 16)
|
|
||||||
local b4 = bit_lshift(load_byte(data, addr + 3), 24)
|
|
||||||
|
|
||||||
return bit_or(b1, b2, b3, b4)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_i8(memory, addr)
|
function load.i64_i8(memory, addr)
|
||||||
local data_1 = load_byte(memory.data, addr)
|
local value = buffer_read_i8(memory.data, addr)
|
||||||
local data_2
|
|
||||||
|
|
||||||
if data_1 >= 0x80 then
|
if value >= 0 then
|
||||||
data_1 = to_u32(data_1 - 0x100)
|
return num_from_u32(value, 0)
|
||||||
data_2 = 0xFFFFFFFF
|
|
||||||
else
|
else
|
||||||
data_2 = 0
|
return num_from_u32(value + 0x100000000, 0xFFFFFFFF)
|
||||||
end
|
end
|
||||||
|
|
||||||
return num_from_u32(data_1, data_2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_u8(memory, addr)
|
function load.i64_u8(memory, addr)
|
||||||
local temp = load_byte(memory.data, addr)
|
return num_from_u32(buffer_read_u8(memory.data, addr), 0)
|
||||||
|
|
||||||
return num_from_u32(temp, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_i16(memory, addr)
|
function load.i64_i16(memory, addr)
|
||||||
local data = memory.data
|
local value = buffer_read_i16(memory.data, addr)
|
||||||
local data_1, data_2
|
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
if value >= 0 then
|
||||||
data_1 = bit_and(data[addr / 4] or 0, 0xFFFF)
|
return num_from_u32(value, 0)
|
||||||
else
|
else
|
||||||
local b1 = load_byte(data, addr)
|
return num_from_u32(value + 0x100000000, 0xFFFFFFFF)
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
|
|
||||||
data_1 = bit_or(b1, b2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if data_1 >= 0x8000 then
|
|
||||||
data_1 = to_u32(data_1 - 0x10000)
|
|
||||||
data_2 = 0xFFFFFFFF
|
|
||||||
else
|
|
||||||
data_2 = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
return num_from_u32(data_1, data_2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_u16(memory, addr)
|
function load.i64_u16(memory, addr)
|
||||||
local data = memory.data
|
return num_from_u32(buffer_read_u16(memory.data, addr), 0)
|
||||||
local temp
|
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
|
||||||
temp = bit_and(data[addr / 4] or 0, 0xFFFF)
|
|
||||||
else
|
|
||||||
local b1 = load_byte(data, addr)
|
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
|
|
||||||
temp = bit_or(b1, b2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return num_from_u32(temp, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_i32(memory, addr)
|
function load.i64_i32(memory, addr)
|
||||||
local data = memory.data
|
local value = buffer_read_i32(memory.data, addr)
|
||||||
local data_1, data_2
|
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
if value >= 0 then
|
||||||
data_1 = data[addr / 4] or 0
|
return num_from_u32(value, 0)
|
||||||
else
|
else
|
||||||
local b1 = load_byte(data, addr)
|
return num_from_u32(value + 0x100000000, 0xFFFFFFFF)
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
local b3 = bit_lshift(load_byte(data, addr + 2), 16)
|
|
||||||
local b4 = bit_lshift(load_byte(data, addr + 3), 24)
|
|
||||||
|
|
||||||
data_1 = bit_or(b1, b2, b3, b4)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if data_1 >= 0x80000000 then
|
|
||||||
data_1 = to_u32(data_1 - 0x100000000)
|
|
||||||
data_2 = 0xFFFFFFFF
|
|
||||||
else
|
|
||||||
data_2 = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
return num_from_u32(data_1, data_2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.i64_u32(memory, addr)
|
function load.i64_u32(memory, addr)
|
||||||
local data = memory.data
|
return num_from_u32(buffer_read_u32(memory.data, addr), 0)
|
||||||
local temp
|
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
|
||||||
temp = data[addr / 4] or 0
|
|
||||||
else
|
|
||||||
local b1 = load_byte(data, addr)
|
|
||||||
local b2 = bit_lshift(load_byte(data, addr + 1), 8)
|
|
||||||
local b3 = bit_lshift(load_byte(data, addr + 2), 16)
|
|
||||||
local b4 = bit_lshift(load_byte(data, addr + 3), 24)
|
|
||||||
|
|
||||||
temp = bit_or(b1, b2, b3, b4)
|
|
||||||
end
|
|
||||||
|
|
||||||
return num_from_u32(temp, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local load_i32 = load.i32
|
|
||||||
|
|
||||||
function load.i64(memory, addr)
|
function load.i64(memory, addr)
|
||||||
local data_1 = load_i32(memory, addr)
|
local data = memory.data
|
||||||
local data_2 = load_i32(memory, addr + 4)
|
local value_1 = buffer_read_u32(data, addr)
|
||||||
|
local value_2 = buffer_read_u32(data, addr + 4)
|
||||||
|
|
||||||
return num_from_u32(data_1, data_2)
|
return num_from_u32(value_1, value_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local load_i64 = load.i64
|
|
||||||
|
|
||||||
function load.f32(memory, addr)
|
function load.f32(memory, addr)
|
||||||
local raw = load_i32(memory, addr)
|
return buffer_read_f32(memory.data, addr)
|
||||||
|
|
||||||
return reinterpret_f32_i32(raw)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.f64(memory, addr)
|
function load.f64(memory, addr)
|
||||||
local raw = load_i64(memory, addr)
|
return buffer_read_f64(memory.data, addr)
|
||||||
|
|
||||||
return reinterpret_f64_i64(raw)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function load.string(memory, addr, len)
|
function load.string(memory, addr, len)
|
||||||
local buffer = table.create(len)
|
local temp = buffer_create(len)
|
||||||
local data = memory.data
|
|
||||||
|
|
||||||
for i = 1, len do
|
buffer_copy(temp, 0, memory.data, addr, len)
|
||||||
local raw = load_byte(data, addr + i - 1)
|
|
||||||
|
|
||||||
buffer[i] = string_char(raw)
|
return buffer_to_string(temp)
|
||||||
end
|
|
||||||
|
|
||||||
return table.concat(buffer)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i32_n8(memory, addr, value)
|
function store.i32_n8(memory, addr, value)
|
||||||
store_byte(memory.data, addr, value)
|
buffer_write_u8(memory.data, addr, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i32_n16(memory, addr, value)
|
function store.i32_n16(memory, addr, value)
|
||||||
store_byte(memory.data, addr, value)
|
buffer_write_u16(memory.data, addr, value)
|
||||||
store_byte(memory.data, addr + 1, bit_rshift(value, 8))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i32(memory, addr, value)
|
function store.i32(memory, addr, value)
|
||||||
local data = memory.data
|
buffer_write_u32(memory.data, addr, value)
|
||||||
|
|
||||||
if addr % 4 == 0 then
|
|
||||||
-- aligned write
|
|
||||||
data[addr / 4] = value
|
|
||||||
else
|
|
||||||
-- unaligned write
|
|
||||||
store_byte(data, addr, value)
|
|
||||||
store_byte(data, addr + 1, bit_rshift(value, 8))
|
|
||||||
store_byte(data, addr + 2, bit_rshift(value, 16))
|
|
||||||
store_byte(data, addr + 3, bit_rshift(value, 24))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local store_i32 = store.i32
|
|
||||||
local store_i32_n8 = store.i32_n8
|
|
||||||
local store_i32_n16 = store.i32_n16
|
|
||||||
|
|
||||||
function store.i64_n8(memory, addr, value)
|
function store.i64_n8(memory, addr, value)
|
||||||
local data_1, _ = num_into_u32(value)
|
local value_1, _ = num_into_u32(value)
|
||||||
|
|
||||||
store_i32_n8(memory, addr, data_1)
|
buffer_write_u8(memory.data, addr, value_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i64_n16(memory, addr, value)
|
function store.i64_n16(memory, addr, value)
|
||||||
local data_1, _ = num_into_u32(value)
|
local value_1, _ = num_into_u32(value)
|
||||||
|
|
||||||
store_i32_n16(memory, addr, data_1)
|
buffer_write_u16(memory.data, addr, value_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i64_n32(memory, addr, value)
|
function store.i64_n32(memory, addr, value)
|
||||||
local data_1, _ = num_into_u32(value)
|
local value_1, _ = num_into_u32(value)
|
||||||
|
|
||||||
store_i32(memory, addr, data_1)
|
buffer_write_u32(memory.data, addr, value_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.i64(memory, addr, value)
|
function store.i64(memory, addr, value)
|
||||||
local data_1, data_2 = num_into_u32(value)
|
local data = memory.data
|
||||||
|
local value_1, value_2 = num_into_u32(value)
|
||||||
|
|
||||||
store_i32(memory, addr, data_1)
|
buffer_write_u32(data, addr, value_1)
|
||||||
store_i32(memory, addr + 4, data_2)
|
buffer_write_u32(data, addr + 4, value_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local store_i64 = store.i64
|
|
||||||
|
|
||||||
function store.f32(memory, addr, value)
|
function store.f32(memory, addr, value)
|
||||||
store_i32(memory, addr, reinterpret_i32_f32(value))
|
buffer_write_f32(memory.data, addr, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.f64(memory, addr, value)
|
function store.f64(memory, addr, value)
|
||||||
store_i64(memory, addr, reinterpret_i64_f64(value))
|
buffer_write_f64(memory.data, addr, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.string(memory, addr, data, len)
|
function store.string(memory, addr, data, len)
|
||||||
len = if len then len else #data
|
local content = if not len or len == #data then data else string_sub(data, 1, len)
|
||||||
|
local temp = buffer_from_string(content)
|
||||||
|
|
||||||
local rem = len % 4
|
buffer_copy(memory.data, addr, temp)
|
||||||
|
|
||||||
for i = 1, len - rem, 4 do
|
|
||||||
local v = string_unpack("<I4", data, i)
|
|
||||||
|
|
||||||
store_i32(memory, addr + i - 1, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = len - rem + 1, len do
|
|
||||||
local v = string_byte(data, i)
|
|
||||||
|
|
||||||
store_i32_n8(memory, addr + i - 1, v)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- FIXME: `store.copy` and `store.fill` should be ideally using the same batched store as `store.string`
|
|
||||||
function store.copy(memory_1, addr_1, memory_2, addr_2, len)
|
function store.copy(memory_1, addr_1, memory_2, addr_2, len)
|
||||||
local data_1 = memory_1.data
|
buffer_copy(memory_1.data, addr_1, memory_2.data, addr_2, len)
|
||||||
local data_2 = memory_2.data
|
|
||||||
|
|
||||||
if addr_1 <= addr_2 then
|
|
||||||
for i = 1, len do
|
|
||||||
local v = load_byte(data_2, addr_2 + i - 1)
|
|
||||||
|
|
||||||
store_byte(data_1, addr_1 + i - 1, v)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for i = len, 1, -1 do
|
|
||||||
local v = load_byte(data_2, addr_2 + i - 1)
|
|
||||||
|
|
||||||
store_byte(data_1, addr_1 + i - 1, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.fill(memory, addr, len, value)
|
function store.fill(memory, addr, len, value)
|
||||||
local data = memory.data
|
buffer_fill(memory.data, addr, value, len)
|
||||||
|
|
||||||
for i = 1, len do
|
|
||||||
store_byte(data, addr + i - 1, value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local WASM_PAGE_SIZE = 65536
|
||||||
|
|
||||||
function allocator.new(min, max)
|
function allocator.new(min, max)
|
||||||
return { min = min, max = max, data = {} }
|
return { max = max, data = buffer_create(min * WASM_PAGE_SIZE) }
|
||||||
|
end
|
||||||
|
|
||||||
|
function allocator.size(memory)
|
||||||
|
return buffer_len(memory.data) / WASM_PAGE_SIZE
|
||||||
end
|
end
|
||||||
|
|
||||||
function allocator.grow(memory, num)
|
function allocator.grow(memory, num)
|
||||||
local old = memory.min
|
local old = allocator.size(memory)
|
||||||
local new = old + num
|
local new = old + num
|
||||||
|
|
||||||
if new > memory.max then
|
if new <= memory.max then
|
||||||
return to_u32(-1)
|
local reallocated = buffer_create(new * WASM_PAGE_SIZE)
|
||||||
else
|
|
||||||
memory.min = new
|
buffer_copy(reallocated, 0, memory.data)
|
||||||
|
|
||||||
|
memory.data = reallocated
|
||||||
|
|
||||||
return old
|
return old
|
||||||
|
else
|
||||||
|
return 0xFFFFFFFF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -977,4 +848,3 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ impl Driver for LoadAt {
|
|||||||
|
|
||||||
impl Driver for MemorySize {
|
impl Driver for MemorySize {
|
||||||
fn write(&self, _mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
fn write(&self, _mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||||
write!(w, "memory_at_{}.min", self.memory())
|
write!(w, "rt.allocator.size(memory_at_{})", self.memory())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ do
|
|||||||
local WASM_PAGE_SIZE = 65536
|
local WASM_PAGE_SIZE = 65536
|
||||||
|
|
||||||
local function is_valid_address(memory, addr, size)
|
local function is_valid_address(memory, addr, size)
|
||||||
return addr >= 0 and addr + size <= memory.min * WASM_PAGE_SIZE
|
return addr >= 0 and addr + size <= rt.allocator.size(memory) * WASM_PAGE_SIZE
|
||||||
end
|
end
|
||||||
|
|
||||||
local function load_checked(name, size)
|
local function load_checked(name, size)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user