Moved ___access_bytes_index___ to the right place
Also, added length test to buffer example
This commit is contained in:
parent
a0d575f61f
commit
4881cb6d4b
@ -38,6 +38,8 @@ WebAssembly.instantiateStreaming(fetch('buffer.wasm'), importObject)
|
||||
let offset = stdlib_types___alloc_bytes__(size)
|
||||
var i8arr = new Uint8Array(app.instance.exports.memory.buffer, offset + 4, size);
|
||||
|
||||
log('len(i8arr) = ' + app.instance.exports.length(offset));
|
||||
|
||||
//Fill it
|
||||
for (var i = 0; i < size; i++) {
|
||||
i8arr[i] = i + 5;
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
@exported
|
||||
def index(inp: bytes, idx: i32) -> i32:
|
||||
return inp[idx]
|
||||
|
||||
@exported
|
||||
def length(inp: bytes) -> i32:
|
||||
return len(inp)
|
||||
|
||||
@ -231,7 +231,7 @@ def expression(inp: ourlang.Expression) -> Statements:
|
||||
|
||||
yield from expression(inp.varref)
|
||||
yield from expression(inp.index)
|
||||
yield wasm.Statement('call', '$___access_bytes_index___')
|
||||
yield wasm.Statement('call', '$stdlib.types.__subscript_bytes__')
|
||||
return
|
||||
|
||||
if isinstance(inp, ourlang.AccessStructMember):
|
||||
@ -381,7 +381,7 @@ def module(inp: ourlang.Module) -> wasm.Module:
|
||||
stdlib_alloc.__find_free_block__,
|
||||
stdlib_alloc.__alloc__,
|
||||
stdlib_types.__alloc_bytes__,
|
||||
_generate____access_bytes_index___(inp),
|
||||
stdlib_types.__subscript_bytes__,
|
||||
] + [
|
||||
function(x)
|
||||
for x in inp.functions.values()
|
||||
@ -413,38 +413,6 @@ def _generate____new_reference___(mod: ourlang.Module) -> wasm.Function:
|
||||
],
|
||||
)
|
||||
|
||||
def _generate____access_bytes_index___(mod: ourlang.Module) -> wasm.Function:
|
||||
return wasm.Function(
|
||||
'___access_bytes_index___',
|
||||
None,
|
||||
[
|
||||
('byt', type_(mod.types['i32']), ),
|
||||
('ofs', type_(mod.types['i32']), ),
|
||||
],
|
||||
[
|
||||
],
|
||||
type_(mod.types['i32']),
|
||||
[
|
||||
wasm.Statement('local.get', '$ofs'),
|
||||
wasm.Statement('local.get', '$byt'),
|
||||
i32.load(),
|
||||
wasm.Statement('i32.lt_u'),
|
||||
|
||||
wasm.Statement('if', comment='$ofs < len($byt)'),
|
||||
wasm.Statement('local.get', '$byt'),
|
||||
wasm.Statement('i32.const', '4', comment='Leading size field'),
|
||||
wasm.Statement('i32.add'),
|
||||
wasm.Statement('local.get', '$ofs'),
|
||||
wasm.Statement('i32.add'),
|
||||
wasm.Statement('i32.load8_u', comment='Within bounds'),
|
||||
wasm.Statement('return'),
|
||||
wasm.Statement('end'),
|
||||
|
||||
wasm.Statement('i32.const', str(0), comment='Out of bounds'),
|
||||
wasm.Statement('return'),
|
||||
],
|
||||
)
|
||||
|
||||
def _generate_tuple_constructor(inp: ourlang.TupleConstructor) -> Statements:
|
||||
yield wasm.Statement('i32.const', str(inp.tuple.alloc_size()))
|
||||
yield wasm.Statement('call', '$___new_reference___')
|
||||
|
||||
@ -113,7 +113,7 @@ def __alloc__(g: Generator, alloc_size: i32) -> i32:
|
||||
g.local.get(alloc_size)
|
||||
g.i32.store()
|
||||
|
||||
# Return address of the allocated bytes
|
||||
# Return address of the allocated memory, skipping the allocator header
|
||||
g.local.get(result)
|
||||
g.i32.const(4) # Header size
|
||||
g.i32.add()
|
||||
|
||||
@ -30,3 +30,37 @@ def __alloc_bytes__(g: Generator, length: i32) -> i32:
|
||||
g.local.get(result)
|
||||
|
||||
return i32('return') # To satisfy mypy
|
||||
|
||||
@func_wrapper()
|
||||
def __subscript_bytes__(g: Generator, adr: i32, ofs: i32) -> i32:
|
||||
"""
|
||||
Returns an index from a bytes value
|
||||
|
||||
If ofs is more than the length of the bytes, this
|
||||
function returns 0, following the 'no undefined behaviour'
|
||||
philosophy.
|
||||
|
||||
adr i32 The pointer for the allocated bytes
|
||||
ofs i32 The offset within the allocated bytes
|
||||
"""
|
||||
g.local.get(ofs)
|
||||
g.local.get(adr)
|
||||
g.i32.load()
|
||||
g.i32.lt_u()
|
||||
|
||||
with g.if_():
|
||||
# The offset is less than the length
|
||||
|
||||
g.local.get(adr)
|
||||
g.i32.const(4) # Bytes header
|
||||
g.i32.add()
|
||||
g.local.get(ofs)
|
||||
g.i32.add()
|
||||
g.i32.load8_u()
|
||||
g.return_()
|
||||
|
||||
# The offset is outside the allocated bytes
|
||||
g.i32.const(0)
|
||||
g.return_()
|
||||
|
||||
return i32('return') # To satisfy mypy
|
||||
|
||||
@ -30,9 +30,11 @@ class Generator_i32:
|
||||
# irelop
|
||||
self.eq = functools.partial(self.generator.add, 'i32.eq')
|
||||
self.ne = functools.partial(self.generator.add, 'i32.ne')
|
||||
self.lt_u = functools.partial(self.generator.add, 'i32.lt_u')
|
||||
|
||||
# 2.4.4. Memory Instructions
|
||||
self.load = functools.partial(self.generator.add, 'i32.load')
|
||||
self.load8_u = functools.partial(self.generator.add, 'i32.load8_u')
|
||||
self.store = functools.partial(self.generator.add, 'i32.store')
|
||||
|
||||
def const(self, value: int, comment: Optional[str] = None) -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user