This also removes the InternalPassAsPointer experiment. This also fixes that u8 values were stores as 32 bits in structs and tuples (but not dynamic arrays since that is special cased as bytes). Also, fixes allocation issue wi th dynamic arrays, it would allocate quadratic amount of memory.
151 lines
3.7 KiB
Python
151 lines
3.7 KiB
Python
import pytest
|
|
import wasmtime
|
|
|
|
from phasm.type3.entry import Type3Exception
|
|
|
|
from ..helpers import Suite
|
|
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, )', (45, 46), 45, ),
|
|
('u8[2]', (45, 46), 45, ),
|
|
('bytes', b'This is a test', 84)
|
|
])
|
|
def test_subscript_0(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u8:
|
|
return f[0]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(in_put)
|
|
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, u8, )', (45, 46, 47), 46, ),
|
|
('u8[5]', (45, 46, 47, 48, 49), 46, ),
|
|
('bytes', b'This is a test', 104)
|
|
])
|
|
def test_subscript_1(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u8:
|
|
return f[1]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(in_put)
|
|
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, u8, )', (45, 46, 47), 47, ),
|
|
('u8[5]', (45, 46, 47, 48, 49), 47, ),
|
|
('bytes', b'This is a test', 105)
|
|
])
|
|
def test_subscript_2(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u8:
|
|
return f[2]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(in_put)
|
|
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, )', (45, 46), 45, ),
|
|
('u8[2]', (45, 46), 45, ),
|
|
('bytes', b'This is a test', 84)
|
|
])
|
|
def test_subscript_invalid_type(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u32:
|
|
return f[0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='u32 must be u8 instead'):
|
|
Suite(code_py).run_code(in_put)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_tuple_must_be_literal():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64), y: u8) -> u64:
|
|
return x[y]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Must index with integer literal'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_tuple_must_be_int():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64)) -> u64:
|
|
return x[0.0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Must index with integer literal'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put', [
|
|
('(u8, u8, )', (45, 46), ),
|
|
('u8[2]', (45, 46), ),
|
|
# dynamic_array isn't known at runtime so works like normal
|
|
])
|
|
def test_subscript_oob_constant_low(type_, in_put):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(x: {type_}) -> u8:
|
|
return x[-1]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Tuple index out of range'):
|
|
Suite(code_py).run_code(in_put)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_oob_constant_high():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64)) -> u64:
|
|
return x[4]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Tuple index out of range'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put', [
|
|
# Cannot Subscript tuple without a constant
|
|
('u8[2]', (45, 46), ),
|
|
('bytes', b'This is a test', ),
|
|
])
|
|
def test_subscript_oob_normal(type_, in_put):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(x: {type_}, y: u32) -> u8:
|
|
return x[y]
|
|
"""
|
|
|
|
with pytest.raises(wasmtime.Trap):
|
|
Suite(code_py).run_code(in_put, 255)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_not_subscriptable():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: u8) -> u8:
|
|
return x[0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='u8 cannot be subscripted'):
|
|
Suite(code_py).run_code()
|