Exemple #1
0
  def generate(self, cls):
    # keeps track of information on variables used in this method
    
    name = self.node.id.name
    rtype = str(self.node.type)
    args = env.getMethodType(cls, name)

    varinfo = {
      'used': 0,
      'labels': 0,
      'class': cls
    }

    body = "\n\ndefine %s {" % methoddefstring(cls, name, args)
    body += "\nentry:"

    for i, formal in enumerate(self.node.formals.children):
      fty = formal.id.type
      body += "\n  %s = alloca %%obj_%s*" % (formal.id.static, fty)
      body += "\n  store %%obj_%s* %%a%d, %%obj_%s** %s" % (fty, i, fty, formal.id.static)
    
    body += self.node.value.codegen.generate(varinfo)

    body += bitcast_if_necessary(varinfo, rtype, varinfo['result_type'], varinfo['result'])

    body += "\n  ret %%obj_%s* %s" % (rtype, varinfo['result'])
    body += "\n}"
    
    code = string_const_code(varinfo)
    code += body

    return code
Exemple #2
0
  def generate(self, varinfo):
    cls = str(self.node.type)
    code = ""

    name = "@%s.%s" % (cls, "_constructor")
    argtypes = env.getMethodType(cls, "_constructor")

    args = ['null']
    for actual,argtype in zip(self.node.actuals.children, argtypes):
      code += actual.codegen.generate(varinfo)
      code += bitcast_if_necessary(varinfo, argtype, varinfo['result_type'], varinfo['result'])
      args.append(varinfo['result'])

    varinfo['result'] = get_next_temp(varinfo)
    varinfo['result_type'] = cls

    code += "\n  ; Calling %s._constructor" %cls
    code += "\n  %s = call %s" % (varinfo['result'], methodcallstring(cls, name, argtypes, args))

    return code
Exemple #3
0
  def generate(self):
    cls = str(self.node.type)

    code = ""

    form = """
%%class_%(name)s = type {
  %%class_%(superclass)s*,
  i8*,
  %(method_types)s
}

@._str.%(name)s = constant [%(len)s x i8] c"%(name)s\\00"
@.str.%(name)s = alias i8* bitcast ([%(len)s x i8]* @._str.%(name)s to i8*)

@%(name)s = global %%class_%(name)s {
  %%class_%(superclass)s* @%(superclass)s,
  i8* @.str.%(name)s,
  %(methods)s
}

%%obj_%(name)s = type {
  %%class_%(name)s*%(field_types)s
}
"""
    
    m = env.getClassMethods(cls)

    alias_strs = []
    alias_form = ("\n@%(class)s.%(method)s = alias %(type)s bitcast "+
      "(%(supertype)s @%(super)s.%(method)s to %(type)s)\n")

    method_consts = [None]*len(m)
    method_types = list(method_consts)
    methods = {}
    for name, (args, pos, inherited_from) in m.iteritems(): 
      typestr = methodtypestring(cls, args)
      method_types[pos] = typestr
      method_consts[pos] = "%s %s" % (typestr, "@%s.%s" % (cls, name))
      methods[name] = typestr

      if inherited_from != cls:
        supertypestr = methodtypestring(inherited_from, args)
        alias_strs.append(alias_form % {
          'class': cls,
          'method': name,
          'type' : typestr,
          'super' : inherited_from,
          'supertype' : supertypestr
        })


    v = env.getClassVars(cls)
    fields = [None]*len(v)
    for name, (ty, pos) in v.iteritems():
      fields[pos] = ",\n  " + (OBJ_PTR % ty)

    code += form % { 
      'name': cls, 
      'len': len(cls)+1,
      'superclass' : self.node.superclass.name,
      'method_types': ",\n  ".join(method_types),
      'methods': ",\n  ".join(method_consts),
      'field_types' : "".join(fields)
    }

    for alias in alias_strs:
      code += alias

    # Constructor...


    constructor = {
      'body': "",
      'class': cls,
      'superclass': self.node.superclass.name,
      'malloc_bytes': (len(fields)+1)*4
    }
    constr_form = """
define %(def)s {
entry:
  %%objstk = alloca %%obj_%(class)s*
  store %%obj_%(class)s* %%child, %%obj_%(class)s** %%objstk
  %%isnull = icmp eq %%obj_%(class)s* %%child, null
  br i1 %%isnull, label %%allocate, label %%initialize
allocate: 
  %%space = call i8* @malloc(i32 %(malloc_bytes)d)
  %%newobj = bitcast i8* %%space to %%obj_%(class)s*
  %%cls_field = getelementptr inbounds %%obj_%(class)s* %%newobj, i32 0, i32 0
  store %%obj_%(class)s* %%newobj, %%obj_%(class)s** %%objstk
  store %%class_%(class)s* @%(class)s, %%class_%(class)s** %%cls_field
  br label %%initialize
initialize:
  %%this = load %%obj_%(class)s** %%objstk
  ; Recursively call our superclass' constructor
  %%as_super = bitcast %%obj_%(class)s* %%this to %%obj_%(superclass)s*
  call %%obj_%(superclass)s* @%(superclass)s._constructor(%%obj_%(superclass)s* %%as_super)

  ;;;; %(class)s class initialization ;;;;
  %(body)s

  ret %%obj_%(class)s* %%this
}
"""
    args = env.getMethodType(cls, "_constructor")
    constructor['def'] = methoddefstring(cls, '_constructor', args, '%child')

    varinfo = {
      'used': 1,
      'labels': 0,
      'class': cls
    }

    for arg, formal in enumerate(self.node.formals.children):
      argname = "%%a%d" % arg
      constructor['body'] += STORE_FIELD % {
        'temp': get_next_temp(varinfo), 
        'class': cls, 
        'loc': formal.id.static + 1,
        'type': str(formal.type),
        'addr': argname
      }

    defs = []
    for feature in self.node.body.children:
      if isinstance(feature, tree.Def):
        defs.append(feature)
      if isinstance(feature, tree.Block):
        constructor['body'] += feature.codegen.generate(varinfo)
      if isinstance(feature, tree.VarInit):
        # Generate code for the expression...
        constructor['body'] += feature.value.codegen.generate(varinfo)
        result = varinfo['result']
        temp = get_next_temp(varinfo)
        constructor['body'] += STORE_FIELD % {
          'temp': temp, 
          'class': cls, 
          'loc': feature.id.static + 1,
          'type': str(feature.type),
          'addr': result
        }

    defcode = ""
    defcode += string_const_code(varinfo)
    defcode += constr_form % constructor

    for method in defs:
      defcode += method.codegen.generate(cls)

    return code, defcode