コード例 #1
0
ファイル: ast_expression.py プロジェクト: mmmulani/cs444
  def c_gen_code(self):
    '''Generate method invocation code'''
    import code_gen.invoke as invoke
    import code_gen.annotate_ids as annotate_ids

    # Get the ASM to push the arguments on the stack left to right.
    args_asm = invoke.get_arg_list(self.arguments)

    # Simple case: The method invocation is just off an ASTIdentifiers.
    if self.right is None:
      ids = self.left
      if len(ids.parts) == 1:
        # Method invocation off implcit "this".  Joos does not allow static
        # methods to be called with an implcit type.
        code = [
          '; Put "this" in eax before calling implicit this method',
          common.get_param('eax', 0, manager.CodeGenManager.N_PARAMS)
        ]
        this_type = manager.CodeGenManager.cur_method.parent_type
        return invoke.call_method_with_final(
            this_type, ids, code, self.arg_types, args_asm)

      annotation = annotate_ids.annotate_identifier(ids)
      if len(annotation) == 0:
        # Call a static method m, since we have handled the implcit "this"
        # case above.
        return invoke.call_static_method(ids, self.arg_types, args_asm)
      return invoke.call_simple_method(ids, self.arg_types, args_asm)

    # If we have a right side, then the left side should be evaluated and
    # the method should be taken off that side.
    left_asm = self.left.c_gen_code()
    left_t = self.left.expr_type
    return invoke.call_method_parts(
        left_t, self.right, left_asm, self.arg_types, args_asm)
コード例 #2
0
ファイル: ast_expression.py プロジェクト: mmmulani/cs444
  def c_gen_code(self):
    import code_gen.annotate_ids as annotate_ids
    import code_gen.access as access
    # Handle the case of a simple name.
    if self.is_simple:
      return access.get_simple_var(self.simple_decl)

    annotation = annotate_ids.annotate_identifier(self)
    if len(annotation) == 0:
      # We should only reach this point if we're trying to resolve
      # ClassName.f, ie. a static field access directly off the type.
      return access.get_simple_static_field(self)

    return access.get_field_access_from_annotation(self, annotation)
コード例 #3
0
ファイル: ast_expression.py プロジェクト: mmmulani/cs444
  def c_gen_code(self):
    import code_gen.access as access
    result = self.right.c_gen_code()

    # The left hand side is either an ASTArrayAccess, ASTFieldAccess or
    # ASTIdentifiers.
    if isinstance(self.left, ASTIdentifiers):
      # For assignment expressions, we evaluate the left hand side first. If
      # the left hand side is an ASTIdentifiers, the same ASTIdentifiers could
      # be used on the right hand side in an assignment.
      # Thus, we must store a reference to where the left hand side points
      # before evaluating the right hand side.

      if self.left.is_simple:
        # If the left hand side is simple, it is either a method parameter,
        # local variable or an instance field on the enclosing type. The
        # location for all of these cannot be altered by the right hand side,
        # so we can calculate the right hand side first.
        return [
          result,
          access.set_simple_var(self.left.simple_decl, 'eax'),
        ]
      else:
        import code_gen.annotate_ids as annotate_ids

        annotations = annotate_ids.annotate_identifier(self.left)
        if len(annotations) == 0:
          # If we do not have any annotations then the left hand side is a
          # static field. This address cannot change.
          return [
            result,
            access.set_simple_static_field(self.left, 'eax'),
          ]
        else:
          # _get_to_final provides code to store a pointer to the second last
          # part of the identifier in $eax.
          type_, code = access._get_to_final(self.left, annotations)
          env = type_.definition.environment

          final_part = str(self.left.parts[-1])
          f, _ = env.lookup_field(final_part)

          return [
            code,
            common.check_null('eax'),
            'push eax ; save instance that we want to store a field on',
            result,
            'pop ebx ; instance to store a field on',
            common.save_instance_field('ebx', f, 'eax'),
          ]

    elif isinstance(self.left, ASTFieldAccess):
      left_asm = self.left.left.c_gen_code()
      left_t = self.left.left.expr_type
      if left_t.is_array:
        raise Exception('Trying to write to array field')
      return [
        '; FieldAccess assignment',
        access.get_field_from_parts(
            left_t, self.left.right, left_asm, get_addr=True),
        'push eax  ; Save field addr',
        result,
        '; RHS of assignment should be eax',
        'pop ebx  ; Pop addr of field',
        'mov [ebx], eax  ; Assign!'
      ]

    elif isinstance(self.left, ASTArrayAccess):
      array_soundness_pass = manager.CodeGenManager.get_label('array_soundness_pass')

      soundness_asm = []
      if not self.left.array_expression.expr_type.is_primitive:
        soundness_asm = [
          'push eax',
          'push ebx',
          'push ecx',
          '; Get CIT of right side',
          'mov ecx, [ecx]'
          '; Get subtype col of right side',
          'mov ecx, [ecx + 4]',
          '; get subtype offset',
          'mov ebx, [ebx + 4]',
          '; index into subtype col',
          'mov ecx, [ecx + ebx]',
          'cmp ecx, 1  ; 1 means that RHS is a subtype of LHS',
          'je {0}'.format(array_soundness_pass),
          'call __exception',
          '{0}:'.format(array_soundness_pass),
          'pop ecx',
          'pop ebx',
          'pop eax',
        ]

      # The result is calculated after the array index offset.
      return [
        self.left.c_gen_code_get_array_pointer(),
        'push ebx ; save array pointer',
        'push eax ; save array offset',
        result,
        'mov ecx, eax ; move result',
        'pop eax ; restore array offset',
        'pop ebx ; restore array pointer',
        '; do array type soundness check',
        soundness_asm,
        'mov [ebx + eax], ecx',
        'mov eax, ecx ; result should be in eax',
      ]

    raise Exception('Programmer error: trying to assign to invalid AST')