コード例 #1
0
def drop_op(config: Configuration) -> None:
    """
    Logic functin for the DROP opcode.
    """
    if config.enable_logic_fn_logging:
        logger.debug("%s()", config.current_instruction.opcode.text)

    config.pop_operand()
コード例 #2
0
ファイル: control.py プロジェクト: metazool/py-wasm
def if_op(config: Configuration) -> None:
    """
    Logic function for the IF opcode
    """
    instruction = cast(If, config.current_instruction)

    if config.enable_logic_fn_logging:
        logger.debug("%s()", instruction.opcode.text)

    value = config.pop_operand()
    arity = len(instruction.result_type)

    if value:
        label = Label(
            arity=arity,
            instructions=instruction.instructions,
            is_loop=False,
        )
    else:
        label = Label(
            arity=arity,
            instructions=instruction.else_instructions,
            is_loop=False,
        )

    config.push_label(label)
コード例 #3
0
ファイル: memory.py プロジェクト: metazool/py-wasm
def store_op(config: Configuration) -> None:
    """
    Logic function for the various *STORE* memory opcodes.
    """
    instruction = cast(MemoryOp, config.current_instruction)
    if config.enable_logic_fn_logging:
        logger.debug("%s()", instruction.opcode.text)

    memarg = instruction.memarg

    memory_address = config.frame_module.memory_addrs[0]
    mem = config.store.mems[memory_address]

    value = config.pop_operand()

    base_offset = config.pop_u32()
    memory_location = numpy.uint32(base_offset + memarg.offset)

    # TODO: update this section to use the `ValType.pack_bytes` API
    if instruction.valtype.is_integer_type:
        wrapped_value = instruction.memory_bit_size.wrap_type(value)
        encoded_value = wrapped_value.tobytes()
    elif instruction.valtype.is_float_type:
        encoded_value = value.tobytes()
    else:
        raise Exception("Invariant")

    assert len(encoded_value) == instruction.memory_bit_size.value // 8
    mem.write(memory_location, encoded_value)
コード例 #4
0
def set_local_op(config: Configuration) -> None:
    """
    Logic functin for the SET_LOCAL opcode.
    """
    instruction = cast(LocalOp, config.current_instruction)
    if config.enable_logic_fn_logging:
        logger.debug("%s()", instruction.opcode.text)

    value = config.pop_operand()
    config.frame_locals[instruction.local_idx] = value
コード例 #5
0
ファイル: control.py プロジェクト: metazool/py-wasm
def _setup_call(config: Configuration,
                function_address: FunctionAddress) -> None:
    """
    Helper function used when entering a new frame during execution.
    """
    function = config.store.funcs[function_address]
    function_args = tuple(
        reversed(
            [config.pop_operand() for _ in range(len(function.type.params))]))
    _setup_function_invocation(config, function_address, function_args)
コード例 #6
0
ファイル: control.py プロジェクト: metazool/py-wasm
def br_if_op(config: Configuration) -> None:
    """
    Logic function for the BR_IF opcode
    """
    if config.enable_logic_fn_logging:
        logger.debug("%s()", config.current_instruction.opcode.text)

    value = config.pop_operand()

    if value:
        instruction = cast(BrIf, config.current_instruction)
        _br(config, instruction.label_idx)
コード例 #7
0
ファイル: numeric.py プロジェクト: metazool/py-wasm
def ieqz_op(config: Configuration) -> None:
    """
    Common logic function for the integer EQZ opcodes
    """
    value = config.pop_operand()
    if config.enable_logic_fn_logging:
        logger.debug("%s(%s)", config.current_instruction.opcode.text, value)

    if value == 0:
        config.push_operand(constants.U32_ONE)
    else:
        config.push_operand(constants.U32_ZERO)
コード例 #8
0
def set_global_op(config: Configuration) -> None:
    """
    Logic functin for the SET_GLOBAL opcode.
    """
    instruction = cast(GlobalOp, config.current_instruction)
    if config.enable_logic_fn_logging:
        logger.debug("%s()", instruction.opcode.text)

    global_address = config.frame_module.global_addrs[instruction.global_idx]
    global_ = config.store.globals[global_address]
    if global_.mut is not Mutability.var:
        raise Exception("Attempt to set immutable global")
    value = config.pop_operand()
    config.store.globals[global_address] = GlobalInstance(global_.valtype, value, global_.mut)
コード例 #9
0
ファイル: control.py プロジェクト: metazool/py-wasm
def _return_from_function(config: Configuration) -> None:
    """
    Helper function for when the control flow for a frame exits.
    """
    valn = tuple(config.pop_operand() for _ in range(config.frame_arity))
    # discard all of the current labels before popping the frame.
    while config.has_active_label:
        config.pop_label()
    config.pop_frame()

    if config.has_active_frame:
        config.extend_operands(valn)
    else:
        config.extend_results(valn)
コード例 #10
0
ファイル: numeric.py プロジェクト: metazool/py-wasm
def ipopcnt_op(config: Configuration) -> None:
    """
    Common logic function for the integer POPCNT opcodes
    """
    instruction = cast(UnOp, config.current_instruction)
    value = config.pop_operand()
    if config.enable_logic_fn_logging:
        logger.debug("%s(%s)", instruction.opcode.text, value)

    if value == 0:
        config.push_operand(instruction.valtype.zero)
    else:
        config.push_operand(
            instruction.valtype.value(bin(int(value)).count('1')))
コード例 #11
0
ファイル: control.py プロジェクト: metazool/py-wasm
def br_table_op(config: Configuration) -> None:
    """
    Logic function for the BR_TABLE opcode
    """
    instruction = cast(BrTable, config.current_instruction)

    if config.enable_logic_fn_logging:
        logger.debug("%s()", instruction.opcode.text)

    label_indices = instruction.label_indices
    default_label_idx = instruction.default_idx

    idx = config.pop_operand()

    if idx < len(label_indices):
        label_idx = label_indices[int(idx)]
        _br(config, label_idx)
    else:
        _br(config, default_label_idx)
コード例 #12
0
ファイル: control.py プロジェクト: metazool/py-wasm
def _br(config: Configuration, label_idx: LabelIdx) -> None:
    """
    Helper function for the BR, BR_IF, and BR_TABLE opcodes.
    """
    label = config.get_label_by_idx(label_idx)
    # take any return values off of the stack before popping labels
    valn = tuple(config.pop_operand() for _ in range(label.arity))

    if label.is_loop:
        # For loops we keep the label which represents the loop on the stack
        # since the continuation of a loop is beginning back at the beginning
        # of the loop itself.
        for _ in range(label_idx):
            config.pop_label()
        config.seek_to_instruction_idx(0)
    else:
        for _ in range(label_idx + 1):
            config.pop_label()

    # put return values back on the stack.
    config.extend_operands(valn)