def gen_creation_expr(info, node, method_obj): canon = node.find_child("Type").canon if canon.endswith('[]'): return gen_creation_expr_array(info, node, method_obj) output = ["; START gen_creation_expr"] # Number of bytes we will malloc (including metadata). num_bytes = info.get_size(canon) output.append("mov eax, %i" % num_bytes) output.append("push ebx") # Safety output.append("call __malloc") output.append("pop ebx") # Safety # Zero out fields. output.append('mov ebx, %d' % (num_bytes / 4)) output.extend(util.gen_zero_out(info)) output.append("mov dword [eax], SIT~%s" % canon) output.append("mov dword [eax+4], SBM~%s" % canon) output.append("mov dword [eax+8], 0") # Not an array, so 0. output.append("push eax ; this pointer") # calculate args, push args; left-to-right args = list(node.find_child("Arguments").children) num_args = len(args) arg_types = [] for arg in args: output.extend(gen_expr(info, arg, method_obj)) output.append("push eax") if typecheck.is_array_type(arg.typ) == True: # '[]'s replaced with '@', so that it can be accepted. arg_types.append(arg.typ[:-2] + '@') else: arg_types.append(arg.typ) constructor_name = canon.split(".")[-1] label = 'CONSTRUCTOR~%s.%s~%s' % (canon, constructor_name, '~'.join(arg_types)) output.append("call %s" % label) # pop args output.append("add esp, %i" % (num_args*4)) # put "this" on eax output.append("pop eax") output.append("; END gen_creation_expr") return output
def gen_creation_expr_array(info, node, method_obj): canon = node.find_child("Type").canon assert canon.endswith('[]') canon = canon[:-2] if canon in primitives.primitive_types: canon = "@" + canon # add @ infront of primitives for SBM output = ["; START gen_creation_expr_array"] # put length of array in eax args = node.find_child("Arguments").children num_args = len(args) if num_args == 1: output.extend(gen_expr(info, args[0], method_obj)) # Array length in eax. else: assert num_args == 0 output.append("mov eax 0") # Calculate number of bytes we need for the array. output.append('push eax') # Save array length. output.append('add eax, 4') output.append('push eax') # Save num words. output.append('shl eax, 2') # Multiply index (offset) by 4. # Allocate. eax has addr. output.append('call __malloc') # Zero out array. output.append('pop ebx') # Num words. output.extend(util.gen_zero_out(info)) # eax = ptr, ebx = num words output.append('pop ebx') # Restore array length. # Object metadata. output.append("mov dword [eax], SIT~java.lang.Object") output.append("mov dword [eax+4], SBM~%s" % canon) output.append("mov dword [eax+8], 1") output.append("mov dword [eax+12], ebx") # Length output.append("; END gen_creation_expr_array") return output
def gen_new_string(info, init_str): output = ['; gen_new_string'] # First we make a char array with length equal to size of init_str num_chars = len(init_str) # Put number of bytes in eax. output.append('mov eax, %d' % ((num_chars + 4) * 4)) # Calculate number of bytes we need for the array. # Allocate. eax has addr. output.append('call __malloc') # Zero out array. output.append('mov ebx, %d' % (num_chars + 4)) output.extend(util.gen_zero_out(info)) # eax = ptr, ebx = num words # Object metadata. output.append("mov dword [eax], SIT~java.lang.Object") output.append("mov dword [eax+4], SBM~@Char") output.append("mov dword [eax+8], 1") output.append("mov dword [eax+12], %d" % num_chars) # Length # Fill in elems. offset = 0 for c in init_str: output.append('mov dword [eax+%d], %d' % (((offset + 4) * 4), ord(c))) offset += 1 # Back up array. output.append('push eax') # Call a new string. # Number of bytes we will malloc (including metadata). num_bytes = info.get_size('java.lang.String') output.append("mov eax, %i" % num_bytes) output.append("call __malloc") # Zero out fields. output.append('mov ebx, %d' % (num_bytes / 4)) output.extend(util.gen_zero_out(info)) output.append("mov dword [eax], SIT~java.lang.String") output.append("mov dword [eax+4], SBM~java.lang.String") output.append("mov dword [eax+8], 0") # Not an array, so 0. # Get the char array. output.append('pop ebx') # Push the string addr, and the char array as an argument. output.append("push eax ; this pointer") output.append('push ebx') # Call the constructor. constructor_label = 'CONSTRUCTOR~java.lang.String.String~Char@' output.append("call %s" % constructor_label) # pop args (only 1) output.append("add esp, 4") # put "this" on eax output.append("pop eax") output.append("; END gen_new_string") return output