MVP #1

Merged
jbwdevries merged 73 commits from idea_crc32 into master 2022-08-21 12:59:21 +00:00
5 changed files with 81 additions and 6 deletions
Showing only changes of commit ad6ca71c53 - Show all commits

View File

@ -13,7 +13,8 @@
# return crc32; # return crc32;
# } # }
_CRC32_Table: [u32] = [ # Might be the wrong table
_CRC32_Table: u32[256] = [
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
@ -80,9 +81,9 @@ _CRC32_Table: [u32] = [
0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
] ]
def _crc32_f(val: u32, byt: u8) -> u32: def _crc32_f(crc: u32, byt: u8) -> u32:
return (val >> 8) ^ _CRC32_Table[(val ^ byt) & 0xFF] return (crc >> 8) ^ _CRC32_Table[(crc & 0xFF) ^ byt]
@exported @exported
def crc32(data: bytes) -> u32: def crc32(data: bytes) -> u32:
return 0xFFFFFFFF ^ foldli(_crc32_f, 0xFFFFFFFF, data) return 0xFFFFFFFF ^ foldl(_crc32_f, 0xFFFFFFFF, data)

View File

@ -77,10 +77,11 @@ OPERATOR_MAP = {
U8_OPERATOR_MAP = { U8_OPERATOR_MAP = {
# Under the hood, this is an i32 # Under the hood, this is an i32
# Implementing XOR, OR is fine since the 3 remaining # Implementing XOR, OR, AND is fine since the 3 remaining
# bytes stay zero after this operation # bytes stay zero after this operation
'^': 'xor', '^': 'xor',
'|': 'or', '|': 'or',
'&': 'and',
} }
U32_OPERATOR_MAP = { U32_OPERATOR_MAP = {
@ -89,6 +90,8 @@ U32_OPERATOR_MAP = {
'<=': 'le_u', '<=': 'le_u',
'>=': 'ge_u', '>=': 'ge_u',
'^': 'xor', '^': 'xor',
'|': 'or',
'&': 'and',
} }
U64_OPERATOR_MAP = { U64_OPERATOR_MAP = {
@ -97,6 +100,8 @@ U64_OPERATOR_MAP = {
'<=': 'le_u', '<=': 'le_u',
'>=': 'ge_u', '>=': 'ge_u',
'^': 'xor', '^': 'xor',
'|': 'or',
'&': 'and',
} }
I32_OPERATOR_MAP = { I32_OPERATOR_MAP = {

View File

@ -248,6 +248,8 @@ class OurVisitor:
operator = '|' operator = '|'
elif isinstance(node.op, ast.BitXor): elif isinstance(node.op, ast.BitXor):
operator = '^' operator = '^'
elif isinstance(node.op, ast.BitAnd):
operator = '&'
else: else:
raise NotImplementedError(f'Operator {node.op}') raise NotImplementedError(f'Operator {node.op}')

View File

@ -0,0 +1,39 @@
import binascii
import struct
import pytest
from .helpers import Suite
@pytest.mark.integration_test
def test_crc32():
# FIXME: Stub
# crc = 0xFFFFFFFF
# byt = 0x61
# => (crc >> 8) ^ _CRC32_Table[(crc & 0xFF) ^ byt]
# (crc >> 8) = 0x00FFFFFF
# => 0x00FFFFFF ^ _CRC32_Table[(crc & 0xFF) ^ byt]
# (crc & 0xFF) = 0xFF
# => 0x00FFFFFF ^ _CRC32_Table[0xFF ^ byt]
# 0xFF ^ 0x61 = 0x9E
# => 0x00FFFFFF ^ _CRC32_Table[0x9E]
# _CRC32_Table[0x9E] = 0x17b7be43
# => 0x00FFFFFF ^ 0x17b7be43
code_py = """
def _crc32_f(crc: u32, byt: u8) -> u32:
return 16777215 ^ 397917763
def testEntry(data: bytes) -> u32:
return 4294967295 ^ _crc32_f(4294967295, data[0])
"""
exp_result = binascii.crc32(b'a')
result = Suite(code_py).run_code(b'a')
# exp_result returns a unsigned integer, as is proper
exp_data = struct.pack('I', exp_result)
# ints extracted from WebAssembly are always signed
data = struct.pack('i', result.returned_value)
assert exp_data == data

View File

@ -62,7 +62,21 @@ def testEntry() -> {type_}:
@pytest.mark.integration_test @pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64']) @pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
def test_xor(type_): def test_bitwise_or(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 10 | 3
"""
result = Suite(code_py).run_code()
assert 11 == result.returned_value
assert TYPE_MAP[type_] == type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
def test_bitwise_xor(type_):
code_py = f""" code_py = f"""
@exported @exported
def testEntry() -> {type_}: def testEntry() -> {type_}:
@ -74,6 +88,20 @@ def testEntry() -> {type_}:
assert 9 == result.returned_value assert 9 == result.returned_value
assert TYPE_MAP[type_] == type(result.returned_value) assert TYPE_MAP[type_] == type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
def test_bitwise_and(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 10 & 3
"""
result = Suite(code_py).run_code()
assert 2 == result.returned_value
assert TYPE_MAP[type_] == type(result.returned_value)
@pytest.mark.integration_test @pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['f32', 'f64']) @pytest.mark.parametrize('type_', ['f32', 'f64'])
def test_buildins_sqrt(type_): def test_buildins_sqrt(type_):