def gen_for_stmt(info, node, method_obj): output = [] # Initialize, if any. if len(node[0].children) == 1: if node[0][0].name == 'LocalVariableDeclaration': output.extend(gen_local_variable_decl(info, node[0][0], method_obj)) else: # expression output.extend(expression.gen_expr(info, node[0][0], method_obj)) loop_lbl = info.get_jump_label() end_lbl = info.get_jump_label() output.append(loop_lbl + ':') # Generate cond, if any. if len(node[1].children) == 1: output.extend(expression.gen_expr(info, node[1][0], method_obj)) output.append('mov ebx, 0') output.append('cmp eax, ebx') output.append('je %s' % end_lbl) # If false, go to end. # Generate body, if any. if len(node[3].children) == 1: output.extend(gen_stmt(info, node[3][0], method_obj)) # Generate update, if any. if len(node[2].children) == 1: output.extend(expression.gen_expr(info, node[2][0], method_obj)) output.append('jmp %s' % loop_lbl) output.append(end_lbl + ':') return output
def gen_static_field_decl(info, node): assert node.name == 'FieldDeclaration' output = [] # If there's no initializer, nothing needs to be done. Otherwise, generate # the expression code and set it. initializer = node[3] if len(initializer.children) == 1: output.extend(expression.gen_expr(info, initializer[0], None)) output.append('mov [%s], eax' % node.label) return output
def gen_return_stmt(info, node, method_obj): output = [] if len(node.children) != 0: output.extend(expression.gen_expr(info, node[0], method_obj)) pass else: output.append("mov eax, %d" % 0xDEADBEEF) output.append("jmp END~%s" % (method_obj.node.label)) return output
def gen_local_variable_decl(info, node, method_obj): output = ["; gen_local_variable_decl"] # Generate the initialization code. output.extend(expression.gen_expr(info, node[2][0], method_obj)) # Get the offset. offset = node.frame_offset * 4 output.append('mov ebx, %d' % offset) # Calculate address and assign. output.append('mov [ebp+ebx], eax') return output
def gen_while_stmt(info, node, method_obj): output = [] loop_lbl = info.get_jump_label() end_lbl = info.get_jump_label() output.append(loop_lbl + ':') # Generate condition. output.extend(expression.gen_expr(info, node[0], method_obj)) output.append('mov ebx, 0') output.append('cmp eax, ebx') output.append('je %s' % end_lbl) # If false, go to end. # Loop body. output.extend(gen_stmt(info, node[1], method_obj)) output.append('jmp %s' % loop_lbl) output.append(end_lbl + ':') return output
def gen_if_stmt(info, node, method_obj): output = [] else_label = info.get_jump_label() end_label = info.get_jump_label() # Check condition. output.extend(expression.gen_expr(info, node[0], method_obj)) output.append('mov ebx, 0') output.append('cmp eax, ebx') output.append('je %s' % else_label) # statement is false, jump to else # True path. output.extend(gen_stmt(info, node[1], method_obj)) output.append('jmp %s' % end_label) # False path. output.append(else_label + ':') if len(node.children) == 3: # If there's an else condition, gen some code output.extend(gen_stmt(info, node[2], method_obj)) output.append(end_label + ':') return output
def gen_expr_stmt(info, node, method_obj): output = [] output.extend(expression.gen_expr(info, node[0], method_obj)) return output
def gen_constructor(info, constructor_obj): node = constructor_obj.node assert node.name == 'ConstructorDeclaration' # Preprocessing: # Assign frame pointer offsets to each parameter and local variable # declaration node. param_start_index = len(node.find_child('Parameters').children) + 1 for decl in node.find_child('Parameters').children: decl.frame_offset = param_start_index param_start_index -= 1 local_var_start_index = -1 num_vars = 0 all_local_decls = list(node.select(['LocalVariableDeclaration'])) for decl in all_local_decls: decl.frame_offset = local_var_start_index local_var_start_index -= 1 num_vars += 1 output = [] # Preamble for constructor. output.append(constructor_obj.node.label + ':') # save ebp & esp output.extend([ "push ebp", "mov ebp, esp", ]) # make room for local vars in the stack output.append("sub esp, %d" % (num_vars*4)) # Call superclass default constructor if this is not java.lang.Object. if info.class_obj.name != 'java.lang.Object': this_offset = (len(constructor_obj.params) * 4) + 8 output.append('mov eax, %d' % this_offset) output.append('mov eax, [eax+ebp]') output.append('push eax') superclass = info.class_obj.extends.name superclass_simple = superclass.split('.')[-1] superclass_label = 'CONSTRUCTOR~%s.%s~' % (superclass, superclass_simple) output.append('call %s' % superclass_label) output.append('add esp, 4') # Initialize instance fields. for member in info.class_obj.declare: if isinstance(member, class_hierarchy.Field) == False: continue field_obj = member field_node = field_obj.node if 'Static' not in field_obj.mods and \ len(field_node[3].children) == 1: # Initializer # Evaluate initializer. output.extend(expression.gen_expr(info, field_node[3][0], constructor_obj)) # Get the address of 'this'. this_offset = (len(constructor_obj.params) * 4) + 8 output.append('mov ebx, ebp') output.append('add ebx, %d' % this_offset) output.append('mov ebx, [ebx]') # Assign to field offset. receiver_type = info.class_obj.name field_name = field_obj.name field_offset = info.get_field_offset_from_field_name(receiver_type, field_name) field_offset += 12 output.append('mov [ebx+%d], eax' % field_offset) body = node # ConstructorBody if len(body.children) != 0: output.extend(statement.gen_block(info, body[3], constructor_obj)) # restore ebp & esp output.extend([ "END~%s:" % (constructor_obj.node.label), "mov esp, ebp", "pop ebp", "ret" ]) return output