Esempio n. 1
0
  def c_gen_code(self):
    import code_gen.asm.common as common
    CodeGenManager.N_PARAMS = self.c_num_params
    CodeGenManager.cur_method = self

    body_code = []
    if self.body:
      body_code = self.body.c_gen_code()

    constructor_code = []
    # Each constructor does the three tasks:
    # 1. Call parent constructor (if one exists).
    # 2. Set field values.
    # 3. Run constructor body.
    if self.is_constructor:
      parent_code = []
      if self.parent_type.canonical_name != 'java.lang.Object':
        super_class = self.parent_type.super[0].definition
        super_sig = (str(super_class.name), [])
        super_constructor, _ = super_class.environment.lookup_method(super_sig,
            constructor=True)

        parent_code = [
          common.get_param('eax', 0, self.c_num_params),
          'push eax',
          'call {0}'.format(super_constructor.c_defn_label),
          'pop ebx ; pop to garbage',
        ]

      field_init_code = []
      for f in self.parent_type.fields:
        if f.is_static:
          continue

        field_init_code.append([
          '; setting value for field {0}'.format(str(f.identifier)),
          'push eax ; save |this|',
          code_gen.asm.object.create_starting_value(f),
          'mov ebx, eax ; move result to ebx',
          'pop eax ; restore |this|',
          common.save_instance_field('eax', f, 'ebx'),
        ])

      constructor_code = [
        parent_code,
        field_init_code,
      ]

    ret = [
      'global {0}'.format(self.c_defn_label),
      '{0}:'.format(self.c_defn_label),
      common.function_prologue(self.c_num_local_vars * 4),
      constructor_code,
      body_code,
      common.function_epilogue(),
    ]

    CodeGenManager.N_PARAMS = 0
    CodeGenManager.cur_method = None
    return ret
Esempio n. 2
0
 def c_gen_code(self):
   asm = []
   # Generate code for the return expression, if there is one
   if self.children[0] is not None:
     asm.append(self.children[0].c_gen_code())
   asm.append(asm_common.function_epilogue())
   return asm
Esempio n. 3
0
def create_array(is_primitive, array_cit_label, subtype_offset = 0):
  ''' Returns code for a function that creates an array in memory.
  This function does NOT include a label, because each reference/primitive
  type will need their own version of this function. You should put your
  own label above this code.

  Structure of the created array object is as follows:
    1. Pointer to Array CIT
    2. The type's subtype column offset for reference types, 0 for primitives
    3. Length (reference to a integer)
    4. Array elements

  1 Param:
    The length of the array (a reference to an integer)'''
  N_PARAMS = 1

  # The first 12 bytes are for the pointer to the Array CIT, the subtype column
  # offset, and the length. Remaining bytes are for the array elements
  # (4 bytes each)

  array_length_pass = CodeGenManager.get_label('array_length_pass')

  return [
    common.function_prologue(),
    common.get_param('ebx', 0, N_PARAMS),
    common.unwrap_primitive('ebx', 'ebx'),
    '; ebx now contains the length of the array',
    '; check that array length is not negative:',
    'cmp ebx, 0',
    'jge {0}'.format(array_length_pass),
    'call __exception',
    '{0}:'.format(array_length_pass),
    'push ebx  ; store the array length (# elems)',
    '; calculate how much memory to allocate, based on length of array:',
    'imul ebx, 4  ; 4 bytes for every element',
    'add ebx, 12  ; add an extra 12 bytes for pointers/length field',
    common.malloc_reg('ebx'),
    'pop ebx  ; restore length (# elems)',
    'mov edx, eax  ; save pointer to array memory in edx',
    'push eax',
    '; set array elems to their default values:',
    _array_init_loop(is_primitive),
    '; create an int to store the length of the array:',
    'push ebx;',
    'call _create_int',
    'pop ecx; pop param to garbage',
    'mov ebx, eax  ; ebx has pointer to integer representing array length',
    'pop eax  ; eax now has pointer to memory from malloc call',
    'mov dword [eax], {0}'.format(array_cit_label),
    'mov dword [eax + 4], {0}'.format(subtype_offset*4),
    'mov dword [eax + 8], ebx',
    common.function_epilogue()
  ]