Ejemplo n.º 1
0
def _compute_table_offsets(
        store: Store, elements: Tuple[ElementSegment, ...],
        module_instance: ModuleInstance) -> Iterator[UInt32]:
    for element_segment in elements:
        frame = Frame(
            module=module_instance,
            locals=[],
            instructions=InstructionSequence(element_segment.offset),
            arity=1,
        )
        config = Configuration(store=store)
        config.push_frame(frame)
        result = config.execute()
        if len(result) != 1:
            raise Exception(
                "Invariant: element segment offset returned empty result")
        offset = UInt32(cast(int, result[0]))

        table_address = module_instance.table_addrs[element_segment.table_idx]
        table_instance = store.tables[table_address]

        if offset + len(element_segment.init) > len(table_instance.elem):
            raise Unlinkable(
                f"Computed element segment offset exceeds table size: {offset} "
                f"+ {len(element_segment.init)} > {len(table_instance.elem)}")
        yield offset
Ejemplo n.º 2
0
def _initialize_globals(
    store: Store,
    module: Module,
    globals_addresses: Tuple[GlobalAddress, ...],
) -> Iterator[UInt32]:
    module_instances = ModuleInstance(
        types=(),
        func_addrs=(),
        memory_addrs=(),
        table_addrs=(),
        global_addrs=globals_addresses,
        exports=(),
    )

    for global_ in module.globals:
        config = Configuration(store=store)
        frame = Frame(
            module=module_instances,
            locals=[],
            instructions=InstructionSequence(global_.init),
            arity=1,
        )
        config.push_frame(frame)
        result = config.execute()
        if len(result) != 1:
            raise Exception(
                "Invariant: globals initialization returned empty result")
        yield UInt32(cast(int, result[0]))
Ejemplo n.º 3
0
def _compute_data_offsets(store: Store, datas: Tuple[DataSegment, ...],
                          module_instance: ModuleInstance) -> Iterator[UInt32]:
    for data_segment in datas:
        frame = Frame(
            module=module_instance,
            locals=[],
            instructions=InstructionSequence(data_segment.offset),
            arity=1,
        )
        config = Configuration(store=store)
        config.push_frame(frame)
        result = config.execute()
        if len(result) != 1:
            raise Exception(
                "Invariant: data segment offset returned empty result")
        offset = UInt32(cast(int, result[0]))

        memory_address = module_instance.memory_addrs[data_segment.memory_idx]
        memory_instance = store.mems[memory_address]

        if offset + len(data_segment.init) > len(memory_instance.data):
            raise Unlinkable(
                f"Computed data segment offset exceeds memory size: {offset} "
                f"+ {len(data_segment.init)} > {len(memory_instance.data)}")
        yield offset
Ejemplo n.º 4
0
 def get_type_for_address(self, address: TAddress) -> TExtern:
     if isinstance(address, FunctionAddress):
         funcinst = self.funcs[address]
         return funcinst.type
     elif isinstance(address, TableAddress):
         tableinst = self.tables[address]
         return TableType(
             limits=Limits(UInt32(len(tableinst.elem)), tableinst.max),
             elem_type=FunctionAddress,
         )
     elif isinstance(address, MemoryAddress):
         meminst = self.mems[address]
         return MemoryType(
             UInt32(len(meminst.data) // constants.PAGE_SIZE_64K),
             meminst.max,
         )
     elif isinstance(address, GlobalAddress):
         globalinst = self.globals[address]
         return GlobalType(
             globalinst.mut,
             globalinst.valtype,
         )
     else:
         raise Exception(f"Invariant: unknown address type: {type(address)}")
Ejemplo n.º 5
0
def parse_u32(stream: io.BytesIO) -> UInt32:
    start_pos = stream.tell()
    value = parse_unsigned_leb128(stream)
    end_pos = stream.tell()

    byte_width = end_pos - start_pos

    if byte_width > 5:  # ceil(32 / 7)
        raise MalformedModule(
            f"encoded u32 exceeds maximum byte width: {byte_width} > 10"
        )
    elif 0 <= value < constants.UINT32_CEIL:
        return UInt32(value)
    elif value < 0:
        raise MalformedModule(
            f"decoded uin32 was not positive: {value}"
        )
    elif value > constants.UINT32_MAX:
        raise MalformedModule(
            f"decoded uin32 is greater than UINT32_MAX: {value} > 2**32 - 1"
        )
    else:
        raise Exception("Invariant")
Ejemplo n.º 6
0
def instantiate_spectest_module(store: Store) -> ModuleInstance:
    logger = logging.getLogger("wasm.tools.fixtures.modules.spectest")

    def spectest__print_i32(store, arg):
        logger.debug('print_i32: %s', arg)
        return store, []

    def spectest__print_i64(store, arg):
        logger.debug('print_i64: %s', arg)
        return store, []

    def spectest__print_f32(store, arg):
        logger.debug('print_f32: %s', arg)
        return store, []

    def spectest__print_f64(store, arg):
        logger.debug('print_f64: %s', arg)
        return store, []

    def spectest__print_i32_f32(store, arg):
        logger.debug('print_i32_f32: %s', arg)
        return store, []

    def spectest__print_f64_f64(store, arg):
        logger.debug('print_f64_f64: %s', arg)
        return store, []

    def spectest__print(store, arg):
        logger.debug('print: %s', arg)
        return store, []

    store.allocate_host_function(FunctionType((ValType.i32, ), ()),
                                 spectest__print_i32)
    store.allocate_host_function(FunctionType((ValType.i64, ), ()),
                                 spectest__print_i64)
    store.allocate_host_function(FunctionType((ValType.f32, ), ()),
                                 spectest__print_f32)
    store.allocate_host_function(FunctionType((ValType.f64, ), ()),
                                 spectest__print_f64)
    store.allocate_host_function(FunctionType((ValType.i32, ValType.f32), ()),
                                 spectest__print_i32_f32)
    store.allocate_host_function(FunctionType((ValType.f64, ValType.f64), ()),
                                 spectest__print_f64_f64)
    store.allocate_host_function(FunctionType((), ()), spectest__print)

    # min:1,max:2 required by import.wast:
    store.allocate_memory(MemoryType(UInt32(1), UInt32(2)))

    # 666 required by import.wast
    store.allocate_global(GlobalType(Mutability.const, ValType.i32),
                          UInt32(666))

    store.allocate_global(GlobalType(Mutability.const, ValType.f32),
                          Float32(0.0))
    store.allocate_global(GlobalType(Mutability.const, ValType.f64),
                          Float64(0.0))
    store.allocate_table(
        TableType(
            Limits(UInt32(10), UInt32(20)),
            FunctionAddress))  # max was 30, changed to 20 for import.wast
    moduleinst = ModuleInstance(
        types=(
            FunctionType((ValType.i32, ), ()),
            FunctionType((ValType.i64, ), ()),
            FunctionType((ValType.f32, ), ()),
            FunctionType((ValType.f64, ), ()),
            FunctionType((ValType.i32, ValType.f32), ()),
            FunctionType((ValType.f64, ValType.f64), ()),
            FunctionType((), ()),
        ),
        func_addrs=tuple(FunctionAddress(idx) for idx in range(7)),
        table_addrs=(TableAddress(0), ),
        memory_addrs=(MemoryAddress(0), ),
        global_addrs=(GlobalAddress(0), GlobalAddress(1)),
        exports=(
            ExportInstance("print_i32", FunctionAddress(0)),
            ExportInstance("print_i64", FunctionAddress(1)),
            ExportInstance("print_f32", FunctionAddress(2)),
            ExportInstance("print_f64", FunctionAddress(3)),
            ExportInstance("print_i32_f32", FunctionAddress(4)),
            ExportInstance("print_f64_f64", FunctionAddress(5)),
            ExportInstance("print", FunctionAddress(6)),
            ExportInstance("memory", MemoryAddress(0)),
            ExportInstance("global_i32", GlobalAddress(0)),
            ExportInstance("global_f32", GlobalAddress(1)),
            ExportInstance("global_f64", GlobalAddress(2)),
            ExportInstance("table", TableAddress(0)),
        ),
    )
    return moduleinst
Ejemplo n.º 7
0
def instantiate_test_module(store):
    def test__func(store, arg):
        pass

    def test__func_i32(store, arg):
        pass

    def test__func_f32(store, arg):
        pass

    def test__func__i32(store, arg):
        pass

    def test__func__f32(store, arg):
        pass

    def test__func_i32_i32(store, arg):
        pass

    def test__func_i64_i64(store, arg):
        pass

    store.allocate_host_function(FunctionType((), ()), test__func)
    store.allocate_host_function(FunctionType((ValType.i32, ), ()),
                                 test__func_i32)
    store.allocate_host_function(FunctionType((ValType.f32, ), ()),
                                 test__func_f32)
    store.allocate_host_function(FunctionType((), (ValType.i32, )),
                                 test__func__i32)
    store.allocate_host_function(FunctionType((), (ValType.f32, )),
                                 test__func__f32)
    store.allocate_host_function(
        FunctionType((ValType.i32, ), (ValType.i32, )), test__func_i32_i32)
    store.allocate_host_function(
        FunctionType((ValType.i64, ), (ValType.i64, )), test__func_i64_i64)

    store.allocate_memory(MemoryType(1, None))
    store.allocate_global(GlobalType(Mutability.const, ValType.i32),
                          UInt32(666))
    store.allocate_global(GlobalType(Mutability.const, ValType.f32),
                          Float32(0.0))
    store.allocate_table(TableType(Limits(10, None), FunctionAddress))
    moduleinst = ModuleInstance(
        types=(
            FunctionType((), ()),
            FunctionType((ValType.i32, ), ()),
            FunctionType((ValType.f32, ), ()),
            FunctionType((), (ValType.i32, )),
            FunctionType((), (ValType.f32, )),
            FunctionType((ValType.i32, ), (ValType.i32, )),
            FunctionType((ValType.i64, ), (ValType.i64, )),
        ),
        func_addrs=tuple(FunctionAddress(idx) for idx in range(7)),
        table_addrs=(TableAddress(0), ),
        memory_addrs=(MemoryAddress(0), ),
        global_addrs=(GlobalAddress(0), GlobalAddress(1)),
        exports=(
            ExportInstance("func", FunctionAddress(0)),
            ExportInstance("func_i32", FunctionAddress(1)),
            ExportInstance("func_f32", FunctionAddress(2)),
            ExportInstance("func__i32", FunctionAddress(3)),
            ExportInstance("func__f32", FunctionAddress(4)),
            ExportInstance("func__i32_i32", FunctionAddress(5)),
            ExportInstance("func__i64_i64", FunctionAddress(6)),
            ExportInstance("memory-2-inf", MemoryAddress(0)),
            ExportInstance("global-i32", GlobalAddress(0)),
            ExportInstance("global-f32", GlobalAddress(1)),
            ExportInstance("table-10-inf", TableAddress(0)),
        ),
    )
    return moduleinst
Ejemplo n.º 8
0
def s32_to_u32(value: SInt32) -> UInt32:
    if value < 0:
        return UInt32(value + constants.UINT32_CEIL)
    else:
        return UInt32(value)