def replace_bytecodes(self): newbc = array('b', [0] * len(self._bytecodes)) idx = 0 i = 0 while i < len(self._bytecodes): bc1 = self._bytecodes[i] len1 = Bytecodes.get_bytecode_length(bc1) if i + len1 >= len(self._bytecodes): # we're over target, so just copy bc1 for j in range(i, i + len1): newbc[idx] = self._bytecodes[j] idx += 1 break newbc[idx] = bc1 idx += 1 # copy args to bc1 for j in range(i + 1, i + len1): newbc[idx] = self._bytecodes[j] idx += 1 i += len1 # update i to point on bc2 # we copy the new array because it may be shorter, and we don't # want to upset whatever dependence there is on the length self._bytecodes = array('b', [0] * idx) for i in range(0, idx): self._bytecodes[i] = newbc[i]
def _compute_stack_depth(self): depth = 0 max_depth = 0 i = 0 while i < len(self._bytecode): bc = self._bytecode[i] if BC.stack_effect_depends_on_send(bc): signature = self._literals[self._bytecode[i + 1]] depth += BC.get_stack_effect(bc, signature.get_number_of_signature_arguments()) else: depth += BC.get_stack_effect(bc) i += BC.get_bytecode_length(bc) if depth > max_depth: max_depth = depth return max_depth
def _compute_stack_depth(self): depth = 0 max_depth = 0 i = 0 while i < len(self._bytecode): bc = self._bytecode[i] if BC.stack_effect_depends_on_send(bc): signature = self._literals[self._bytecode[i + 1]] depth += BC.get_stack_effect( bc, signature.get_number_of_signature_arguments()) else: depth += BC.get_stack_effect(bc) i += BC.get_bytecode_length(bc) if depth > max_depth: max_depth = depth return max_depth
def start(self): try: # Iterate through the bytecodes while True: # Get the current bytecode index bytecode_index = self.get_frame().get_bytecode_index() # Get the current bytecode bytecode = self.get_method().get_bytecode(bytecode_index) # Get the length of the current bytecode bytecode_length = Bytecodes.get_bytecode_length(bytecode) # Compute the next bytecode index next_bytecode_index = bytecode_index + bytecode_length # Update the bytecode index of the frame self.get_frame().set_bytecode_index(next_bytecode_index) # Handle the current bytecode self._dispatch_table[bytecode](bytecode_index) except self.InterpreterHalt: return self.get_frame().get_stack_element(0)
def dump_method(cls, m, indent): Universe.error_println("(") # output stack information Universe.error_println("%s<%d locals, %d stack, %d bc_count>" % (indent, m.get_number_of_locals().get_embedded_integer(), m.get_maximum_number_of_stack_elements().get_embedded_integer(), m.get_number_of_bytecodes())) # output bytecodes b = 0 while b < m.get_number_of_bytecodes(): Universe.error_print(indent) # bytecode index if b < 10: Universe.error_print(" ") if b < 100: Universe.error_print(" ") Universe.error_print(" %d:" % b) # mnemonic bytecode = m.get_bytecode(b) Universe.error_print(Bytecodes.as_str(bytecode) + " ") # parameters (if any) if Bytecodes.get_bytecode_length(bytecode) == 1: Universe.error_println() b += 1 continue if bytecode == Bytecodes.push_local: Universe.error_println("local: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.push_argument: Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) + ", context " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.push_field: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1)))) elif bytecode == Bytecodes.push_block: Universe.error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ") cls.dump_method(m.get_constant(b), indent + "\t") elif bytecode == Bytecodes.push_constant: constant = m.get_constant(b) Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") value: (" + str(constant.get_class().get_name()) + ") " + str(constant)) elif bytecode == Bytecodes.push_global: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") value: " + str(m.get_constant(b))) elif bytecode == Bytecodes.pop_local: Universe.error_println("local: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.pop_argument: Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.pop_field: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1)))) elif bytecode == Bytecodes.send: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") signature: " + str(m.get_constant(b))) elif bytecode == Bytecodes.super_send: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") signature: " + str(m.get_constant(b))) else: Universe.error_println("<incorrect bytecode>") b += Bytecodes.get_bytecode_length(m.get_bytecode(b)) Universe.error_println(indent + ")")
def dump_method(cls, m, indent): Universe.error_println("(") # output stack information Universe.error_println( "%s<%d locals, %d stack, %d bc_count>" % (indent, m.get_number_of_locals().get_embedded_integer(), m.get_maximum_number_of_stack_elements().get_embedded_integer(), m.get_number_of_bytecodes())) # output bytecodes b = 0 while b < m.get_number_of_bytecodes(): Universe.error_print(indent) # bytecode index if b < 10: Universe.error_print(" ") if b < 100: Universe.error_print(" ") Universe.error_print(" %d:" % b) # mnemonic bytecode = m.get_bytecode(b) Universe.error_print(Bytecodes.as_str(bytecode) + " ") # parameters (if any) if Bytecodes.get_bytecode_length(bytecode) == 1: Universe.error_println() b += 1 continue if bytecode == Bytecodes.push_local: Universe.error_println("local: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.push_argument: Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) + ", context " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.push_field: Universe.error_println( "(index: " + str(m.get_bytecode(b + 1)) + ") field: " + str(m.get_holder().get_instance_field_name( m.get_bytecode(b + 1)))) elif bytecode == Bytecodes.push_block: Universe.error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ") cls.dump_method(m.get_constant(b), indent + "\t") elif bytecode == Bytecodes.push_constant: constant = m.get_constant(b) Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") value: (" + str(constant.get_class().get_name()) + ") " + str(constant)) elif bytecode == Bytecodes.push_global: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") value: " + str(m.get_constant(b))) elif bytecode == Bytecodes.pop_local: Universe.error_println("local: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.pop_argument: Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) + ", context: " + str(m.get_bytecode(b + 2))) elif bytecode == Bytecodes.pop_field: Universe.error_println( "(index: " + str(m.get_bytecode(b + 1)) + ") field: " + str(m.get_holder().get_instance_field_name( m.get_bytecode(b + 1)))) elif bytecode == Bytecodes.send: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") signature: " + str(m.get_constant(b))) elif bytecode == Bytecodes.super_send: Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) + ") signature: " + str(m.get_constant(b))) else: Universe.error_println("<incorrect bytecode>") b += Bytecodes.get_bytecode_length(m.get_bytecode(b)) Universe.error_println(indent + ")")