Ejemplo n.º 1
0
def _build_call(state, addr, instruction):
    call = nodes.FunctionCall()
    call.function = _build_slot(state, addr, instruction.A)
    call.arguments.contents = _build_call_arguments(state, addr, instruction)

    line_marked = [call]

    if instruction.opcode <= ins.CALL.opcode:
        if instruction.B == 0:
            node = nodes.Assignment()
            node.destinations.contents.append(nodes.MULTRES())
            node.expressions.contents.append(call)
        elif instruction.B == 1:
            node = call
        else:
            from_slot = instruction.A
            to_slot = instruction.A + instruction.B - 2
            node = _build_range_assignment(state, addr, from_slot, to_slot)
            node.expressions.contents.append(call)
    else:
        assert instruction.opcode <= ins.CALLT.opcode
        node = nodes.Return()
        node.returns.contents.append(call)
        line_marked.append(node)

    return node, line_marked
Ejemplo n.º 2
0
def _build_class_assignment(addr, slot, class_name):
    assignment = nodes.Assignment()

    destination = _build_identifier_name(
        addr, slot, nodes.Identifier.T_LOCAL, class_name)

    assignment.destinations.contents.append(destination)

    return assignment
Ejemplo n.º 3
0
def _build_table_assignment(state, addr, instruction):
    assignment = nodes.Assignment()

    destination = _build_table_element(state, addr, instruction)
    expression = _build_slot(state, addr, instruction.A)

    assignment.destinations.contents.append(destination)
    assignment.expressions.contents.append(expression)

    return assignment
Ejemplo n.º 4
0
def _build_global_assignment(state, addr, instruction):
    assignment = nodes.Assignment()

    variable = _build_global_variable(state, addr, instruction.CD)
    expression = _build_slot(state, addr, instruction.A)

    assignment.destinations.contents.append(variable)
    assignment.expressions.contents.append(expression)

    return assignment
Ejemplo n.º 5
0
def _build_vararg(state, addr, instruction):
    base = instruction.A
    last_slot = base + instruction.B - 2

    if last_slot < base:
        node = nodes.Assignment()
        node.destinations.contents.append(nodes.MULTRES())
        node.expressions.contents.append(nodes.Vararg())
    else:
        node = _build_range_assignment(state, addr, base, last_slot)
        node.expressions.contents.append(nodes.Vararg())

    return node
Ejemplo n.º 6
0
def _build_table_mass_assignment(state, addr, instruction):
    assignment = nodes.Assignment()

    base = instruction.A

    destination = nodes.TableElement()
    destination.key = nodes.MULTRES()
    destination.table = _build_slot(state, addr, base - 1)

    assignment.destinations.contents = [destination]
    assignment.expressions.contents = [nodes.MULTRES()]

    return assignment
Ejemplo n.º 7
0
def _build_range_assignment(state, addr, from_slot, to_slot):
    assignment = nodes.Assignment()

    slot = from_slot

    assert from_slot <= to_slot

    while slot <= to_slot:
        destination = _build_slot(state, addr, slot)

        assignment.destinations.contents.append(destination)

        slot += 1

    return assignment
Ejemplo n.º 8
0
def _unwarp_logical_expression(start, end, body):
	slot = _find_expression_slot(body)

	assert slot is not None

	true, false, body = _get_terminators(body)

	expression = _compile_expression([start] + body, end, true, false)

	dst = copy.deepcopy(slot)

	assignment = nodes.Assignment()
	assignment.destinations.contents.append(dst)
	assignment.expressions.contents.append(expression)

	start.contents.append(assignment)
Ejemplo n.º 9
0
def _unwarp_logical_expression(start, end, body):
    slot = _find_expression_slot(body)

    assert slot is not None

    true, false, body = _get_terminators(body)
    #print("\n\n>>>>> start: " + str(start) + "\n\n\tBODY: " + str(body[0]))
    #print("\n\nend: " + str(end) + " \n\ntrue: " + str(true) + "\n\nfalse: " + str(false))
    #print("\n\ntrue: " + str(true) + "\nfalse: " + str(false) + "\nbody: " + str(body[0]))
    expression = _compile_expression([start] + body, end, true, false)

    dst = copy.deepcopy(slot)

    assignment = nodes.Assignment()
    assignment.destinations.contents.append(dst)
    assignment.expressions.contents.append(expression)

    start.contents.append(assignment)
Ejemplo n.º 10
0
def _build_call(state, addr, instruction):
    call = nodes.FunctionCall()
    call.function = _build_slot(state, addr, instruction.A)
    call.arguments.contents = _build_call_arguments(state, addr, instruction)
    call.name = _lookup_variable_name(state, addr, instruction.A)
    if gconfig.gVerbose:
        print("_build_call " + call.name)

    # CALLM Call: A, ..., A+B-2 = A(A+1, ..., A+C+MULTRES)
    # CALL Call: A, ..., A+B-2 = A(A+1, ..., A+C-1)
    if instruction.opcode <= ins.CALL.opcode:
        if instruction.B == 0:
            node = nodes.Assignment()
            node.destinations.contents.append(nodes.MULTRES())
            node.expressions.contents.append(call)
        elif instruction.B == 1:
            node = call
        # elif call.name and call.name == "class" and instruction.B == 2:
        #     class_name = _lookup_variable_name(state, addr, instruction.A+1)
        #     print("class " + class_name)
        #     assert class_name is not None
        #     node = _build_class_assignment(addr, instruction.A, class_name)
        #     node.expressions.contents.append(call)
        else:
            from_slot = instruction.A
            to_slot = instruction.A + instruction.B - 2
            node = _build_range_assignment(state, addr, from_slot, to_slot)
            node.expressions.contents.append(call)
    # CALLMT Tailcall: return A(A+1, ..., A+D+MULTRES)
    # CALLT Tailcall: return A(A+1, ..., A+D-1)
    else:
        assert instruction.opcode <= ins.CALLT.opcode
        node = nodes.Return()
        node.returns.contents.append(call)

    return node
Ejemplo n.º 11
0
def _build_var_assignment(state, addr, instruction):
    opcode = instruction.opcode

    assignment = nodes.Assignment()

    if instruction.A_type == ins.T_DST:
        destination = _build_slot(state, addr, instruction.A)
    else:
        assert instruction.A_type == ins.T_UV

        destination = _build_upvalue(state, addr, instruction.A)

    assignment.destinations.contents.append(destination)

    # Unary assignment operators (A = op D)
    if opcode == ins.MOV.opcode \
            or opcode == ins.NOT.opcode \
            or opcode == ins.UNM.opcode \
            or (ljd.config.version_config.use_version > 2.0 and opcode == ins.ISTYPE.opcode) \
            or (ljd.config.version_config.use_version > 2.0 and opcode == ins.ISNUM.opcode) \
            or opcode == ins.LEN.opcode:
        expression = _build_unary_expression(state, addr, instruction)

    # Binary assignment operators (A = B op C)
    elif opcode <= ins.POW.opcode:
        expression = _build_binary_expression(state, addr, instruction)

    # Concat assignment type (A = B .. B + 1 .. ... .. C - 1 .. C)
    elif opcode == ins.CAT.opcode:
        expression = _build_concat_expression(state, addr, instruction)

    # Constant assignment operators except KNIL, which is weird anyway
    elif opcode <= ins.KPRI.opcode:
        expression = _build_const_expression(state, addr, instruction)

    elif opcode == ins.UGET.opcode:
        expression = _build_upvalue(state, addr, instruction.CD)

    elif opcode == ins.USETV.opcode:
        expression = _build_slot(state, addr, instruction.CD)

    elif opcode <= ins.USETP.opcode:
        expression = _build_const_expression(state, addr, instruction)

    elif opcode == ins.FNEW.opcode:
        expression = _build_function(state, instruction.CD,
                                     destination.slot + destination.slot_index)

    elif opcode == ins.TNEW.opcode:
        expression = nodes.TableConstructor()

    elif opcode == ins.TDUP.opcode:
        expression = _build_table_copy(state, instruction.CD)

    elif opcode == ins.GGET.opcode:
        expression = _build_global_variable(state, addr, instruction.CD)

    else:
        if ljd.config.version_config.use_version > 2.0:
            assert opcode <= ins.TGETR.opcode
            expression = _build_table_element(state, addr, instruction)
        else:
            assert opcode <= ins.TGETB.opcode
            expression = _build_table_element(state, addr, instruction)

    assignment.expressions.contents.append(expression)

    return assignment