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)
|
let offset = stdlib_types___alloc_bytes__(size)
|
||||||
var i8arr = new Uint8Array(app.instance.exports.memory.buffer, offset + 4, size);
|
var i8arr = new Uint8Array(app.instance.exports.memory.buffer, offset + 4, size);
|
||||||
|
|
||||||
|
log('len(i8arr) = ' + app.instance.exports.length(offset));
|
||||||
|
|
||||||
//Fill it
|
//Fill it
|
||||||
for (var i = 0; i < size; i++) {
|
for (var i = 0; i < size; i++) {
|
||||||
i8arr[i] = i + 5;
|
i8arr[i] = i + 5;
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
@exported
|
@exported
|
||||||
def index(inp: bytes, idx: i32) -> i32:
|
def index(inp: bytes, idx: i32) -> i32:
|
||||||
return inp[idx]
|
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.varref)
|
||||||
yield from expression(inp.index)
|
yield from expression(inp.index)
|
||||||
yield wasm.Statement('call', '$___access_bytes_index___')
|
yield wasm.Statement('call', '$stdlib.types.__subscript_bytes__')
|
||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(inp, ourlang.AccessStructMember):
|
if isinstance(inp, ourlang.AccessStructMember):
|
||||||
@ -381,7 +381,7 @@ def module(inp: ourlang.Module) -> wasm.Module:
|
|||||||
stdlib_alloc.__find_free_block__,
|
stdlib_alloc.__find_free_block__,
|
||||||
stdlib_alloc.__alloc__,
|
stdlib_alloc.__alloc__,
|
||||||
stdlib_types.__alloc_bytes__,
|
stdlib_types.__alloc_bytes__,
|
||||||
_generate____access_bytes_index___(inp),
|
stdlib_types.__subscript_bytes__,
|
||||||
] + [
|
] + [
|
||||||
function(x)
|
function(x)
|
||||||
for x in inp.functions.values()
|
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:
|
def _generate_tuple_constructor(inp: ourlang.TupleConstructor) -> Statements:
|
||||||
yield wasm.Statement('i32.const', str(inp.tuple.alloc_size()))
|
yield wasm.Statement('i32.const', str(inp.tuple.alloc_size()))
|
||||||
yield wasm.Statement('call', '$___new_reference___')
|
yield wasm.Statement('call', '$___new_reference___')
|
||||||
|
|||||||
@ -113,7 +113,7 @@ def __alloc__(g: Generator, alloc_size: i32) -> i32:
|
|||||||
g.local.get(alloc_size)
|
g.local.get(alloc_size)
|
||||||
g.i32.store()
|
g.i32.store()
|
||||||
|
|
||||||
# Return address of the allocated bytes
|
# Return address of the allocated memory, skipping the allocator header
|
||||||
g.local.get(result)
|
g.local.get(result)
|
||||||
g.i32.const(4) # Header size
|
g.i32.const(4) # Header size
|
||||||
g.i32.add()
|
g.i32.add()
|
||||||
|
|||||||
@ -30,3 +30,37 @@ def __alloc_bytes__(g: Generator, length: i32) -> i32:
|
|||||||
g.local.get(result)
|
g.local.get(result)
|
||||||
|
|
||||||
return i32('return') # To satisfy mypy
|
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
|
# irelop
|
||||||
self.eq = functools.partial(self.generator.add, 'i32.eq')
|
self.eq = functools.partial(self.generator.add, 'i32.eq')
|
||||||
self.ne = functools.partial(self.generator.add, 'i32.ne')
|
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
|
# 2.4.4. Memory Instructions
|
||||||
self.load = functools.partial(self.generator.add, 'i32.load')
|
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')
|
self.store = functools.partial(self.generator.add, 'i32.store')
|
||||||
|
|
||||||
def const(self, value: int, comment: Optional[str] = None) -> None:
|
def const(self, value: int, comment: Optional[str] = None) -> None:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user