67 lines
1.6 KiB
Python
67 lines
1.6 KiB
Python
"""
|
|
stdlib: Standard types that are not wasm primitives
|
|
"""
|
|
from phasm.wasmgenerator import Generator, VarType_i32 as i32, func_wrapper
|
|
|
|
from phasm.stdlib import alloc
|
|
|
|
@func_wrapper()
|
|
def __alloc_bytes__(g: Generator, length: i32) -> i32:
|
|
"""
|
|
Allocates room for a bytes instance, but does not write
|
|
anything to the allocated memory
|
|
"""
|
|
result = i32('result')
|
|
|
|
# Allocate the length of the byte string, as well
|
|
# as 4 bytes for a length header
|
|
g.local.get(length)
|
|
g.i32.const(4)
|
|
g.i32.add()
|
|
g.call(alloc.__alloc__)
|
|
|
|
# Store the address in a variable so we can use it up
|
|
# for writing the length header
|
|
g.local.tee(result)
|
|
g.local.get(length)
|
|
g.i32.store()
|
|
|
|
# Get the address back from the variable as return
|
|
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
|