def add_alloc_proto(self): ctype = cnorm.nodes.FuncType(self.ident, [], cnorm.nodes.PointerType()) decl = cnorm.nodes.Decl('alloc', ctype) dec_n = mangler.muckFangle(decl, self.ident) decl._name = dec_n setattr(decl, 'saved_name', 'alloc') self.protos.append(decl)
def __init__(self, ident, statement, flag): # Declarations self.decls = [] self.decls_vars = [] for st in statement.body: st.saved_name = st._name st._name = mangler.muckFangle(st, ident) if not isinstance(st._ctype, cnorm.nodes.FuncType): self.decls_vars.append(st) tmp = deepcopy(st) if hasattr(tmp, '_assign_expr'): delattr(tmp, '_assign_expr') tmp._ctype._storage = 4 self.decls.append(tmp) else: self.decls.append(st) # Nom du module self.ident = ident # Tout ce qui doit etre mis dans le fichier de sortie (extern, ...) self.out = [] # Declaration trouvee dans le fichier courrant ou non self.recurs = flag
def add_virtual_members(self): for decl in self.non_mangled: vir_name = mangler.mimpleSangle(decl) for idx, dcl in enumerate(self.vt._ctype.fields): if dcl._name == vir_name: m_name = mangler.muckFangle(decl, self.ident) self.inst_vt._assign_expr.body[idx].params[0].value = m_name
def add_virtual_members(self): for decl in self.non_mangled: vir_name = mangler.mimpleSangle(decl) for idx, dcl in enumerate(self.vt._ctype.fields): if dcl._name == vir_name: m_name = mangler.muckFangle(decl, self.ident) self.inst_vt._assign_expr.body[idx].params[ 0].value = m_name
def register_implementation(self, imp): ret = self.check_param(imp) if ret != None: self.imps.append(ret) if '$init$' in ret._name and self.ident in decl_keeper.classes: self.create_new_fct(ret) else: imp._name = mangler.muckFangle(imp, self.ident) self.imps.append(imp)
def add_legacy_fcts(self): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; void delete(%s*); """ % (self.ident, self.ident, self.ident)) decl = res.body[1] decl._name = mangler.muckFangle(decl, self.ident) setattr(decl, 'saved_name', 'delete') self.members.append(decl)
def add_new_proto(self, decl): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *new(%s); """ % (self.ident, self.ident, self.ident, ', '.join([str(c.to_c()).rstrip() for c in decl._ctype.params]).replace(';', ''))) dcl = res.body[1] dcl._name = mangler.muckFangle(dcl, self.ident) setattr(decl, 'saved_name', 'new') self.protos.append(dcl)
def add_new_proto(self, decl): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *new(%s); """ % (self.ident, self.ident, self.ident, ', '.join( [str(c.to_c()).rstrip() for c in decl._ctype.params]).replace(';', ''))) dcl = res.body[1] dcl._name = mangler.muckFangle(dcl, self.ident) setattr(decl, 'saved_name', 'new') self.protos.append(dcl)
def mangle_virtuals(self): new_dict = {} for vir in self.virtuals: m_name = mangler.muckFangle(self.virtuals[vir], self.ident) v_name = mangler.mimpleSangle(self.virtuals[vir]) v_obj = deepcopy(self.virtuals[vir]) v_obj._name = v_name new_dict[v_name] = v_obj proto = deepcopy(v_obj) proto._name = m_name self.protos.append(proto) self.virtuals = new_dict
def create_alloc_fct(self): d = Declaration() res = d.parse(""" typedef struct _kc_%s %s; %s *alloc() { %s *self; self = malloc(sizeof(%s)); return (self); } """ % (self.ident, self.ident, self.ident, self.ident, self.ident)) for decl in res.body: if isinstance(decl._ctype, cnorm.nodes.FuncType): decl._name = mangler.muckFangle(decl, self.ident) self.alloc_fct = decl self.imps.append(decl)
def instanciate_vt(self): m_inst_vt = None if self.ident in decl_keeper.inher: mom_name = decl_keeper.inher[self.ident] m_inst_vt = decl_keeper.classes[mom_name].inst_vt else: m_inst_vt = decl_keeper.obj_vtable blockInit = deepcopy(m_inst_vt._assign_expr) # Réassignation des pointeurs size_b = len(blockInit.body) size_v = len(self.vt._ctype.fields) if size_v > size_b: diff = size_v - size_b for i in range(0, diff): blockInit.body.append(None) for vir_name in self.virtuals: idx = None tmp_name = mangler.mimpleSangle(self.virtuals[vir_name]) for index, tp in enumerate(self.vt._ctype.fields): if tp._name == tmp_name: idx = index if idx == None: continue fct = self.virtuals[vir_name] m_name = mangler.muckFangle(fct, self.ident) blockInit.body[idx] = cnorm.nodes.Unary(cnorm.nodes.Raw('&'), [cnorm.nodes.Id(m_name)]) decl = cnorm.nodes.Decl('vtable_%s' % self.ident, cnorm.nodes.PrimaryType('vt_%s' % self.ident)) setattr(decl, '_assign_expr', blockInit) self.inst_vt = decl self.add_virtual_members() self.mangle_virtuals() ext = deepcopy(self.inst_vt) delattr(ext, '_assign_expr') ext._ctype._storage = cnorm.nodes.Storages.EXTERN return ext
def create_delete_fct(self): d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; typedef struct _kc_vt_%s vt_%s; void delete(%s *self) { ((vt_%s*)((Object*)self)->vt)->clean(self); } """ % (self.ident, self.ident, self.ident, self.ident, self.ident, self.ident)) for decl in res.body: if isinstance(decl._ctype, cnorm.nodes.FuncType): decl._name = mangler.muckFangle(decl, self.ident) for dcl in decl.body.body: if hasattr(dcl.expr, 'call_expr') and hasattr(dcl.expr.call_expr, 'params') \ and dcl.expr.call_expr.params[0].value == 'clean': dcl.expr.call_expr.params[0].value = 'clean$$void' self.imps.append(decl)
def create_new_fct(self, ini): params = [] if len(ini._ctype._params) >= 1: params = ini._ctype._params[1:] d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; %s *new(%s) { %s* self; self = alloc(); init(self, %s); ((Object*)self)->name = "%s"; return (self); } """ % (self.ident, self.ident, self.ident, ', '.join( [str(c.to_c()).rstrip() for c in params]).replace(';', ''), self.ident, ', '.join( [c._name for c in params]), self.ident)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'new': decl._name = mangler.muckFangle(decl, self.ident) decl.body.body[4:4] = self.create_decl_malloc( self.get_inheritance(self.ident, [])) for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance(dcl.expr, cnorm.nodes.Binary) and\ (isinstance(dcl.expr.params[0], cnorm.nodes.Arrow) or \ isinstance(dcl.expr.params[0], cnorm.nodes.Array)): pass elif isinstance(dcl.expr, cnorm.nodes.Binary): dcl.expr.params[ 1].call_expr.value = self.alloc_fct._name elif isinstance(dcl.expr, cnorm.nodes.Func): dcl.expr.call_expr.value = ini._name self.imps.append(decl)
def check_param(self, decl): if hasattr(decl, '_ctype') and isinstance(decl._ctype, cnorm.nodes.FuncType): if not self.ident in decl_keeper.classes: return None cl = decl_keeper.classes[self.ident] param = cnorm.nodes.Decl('self', cnorm.nodes.PrimaryType(self.ident)) param._ctype._decltype = cnorm.nodes.PointerType() if decl._ctype._params != [] and decl._ctype._params[0]._ctype._identifier == self.ident: return None dc = deepcopy(decl) dc._ctype._params.insert(0, param) sm_name = mangler.mimpleSangle(dc) dc._name = mangler.muckFangle(dc, self.ident) for dcl in cl.members: if dcl._name == dc._name: return dc if sm_name in cl.virtuals: return dc return None
def create_new_fct(self, ini): params = [] if len(ini._ctype._params) >= 1: params = ini._ctype._params[1:] d = Declaration() res = d.parse(""" typedef struct _kc_Object Object; typedef struct _kc_%s %s; %s *new(%s) { %s* self; self = alloc(); init(self, %s); ((Object*)self)->name = "%s"; return (self); } """ % (self.ident, self.ident, self.ident, ', '.join([str(c.to_c()).rstrip() for c in params]).replace(';', ''), self.ident, ', '.join([c._name for c in params]), self.ident)) for decl in res.body: if hasattr(decl, '_name') and decl._name == 'new': decl._name = mangler.muckFangle(decl, self.ident) decl.body.body[4:4] = self.create_decl_malloc(self.get_inheritance(self.ident, [])) for dcl in decl.body.body: if isinstance(dcl, cnorm.nodes.ExprStmt): if isinstance(dcl.expr, cnorm.nodes.Binary) and\ (isinstance(dcl.expr.params[0], cnorm.nodes.Arrow) or \ isinstance(dcl.expr.params[0], cnorm.nodes.Array)): pass elif isinstance(dcl.expr, cnorm.nodes.Binary): dcl.expr.params[1].call_expr.value = self.alloc_fct._name elif isinstance(dcl.expr, cnorm.nodes.Func): dcl.expr.call_expr.value = ini._name self.imps.append(decl)
def check_param(self, decl): if hasattr(decl, '_ctype') and isinstance(decl._ctype, cnorm.nodes.FuncType): if not self.ident in decl_keeper.classes: return None cl = decl_keeper.classes[self.ident] param = cnorm.nodes.Decl('self', cnorm.nodes.PrimaryType(self.ident)) param._ctype._decltype = cnorm.nodes.PointerType() if decl._ctype._params != [] and decl._ctype._params[ 0]._ctype._identifier == self.ident: return None dc = deepcopy(decl) dc._ctype._params.insert(0, param) sm_name = mangler.mimpleSangle(dc) dc._name = mangler.muckFangle(dc, self.ident) for dcl in cl.members: if dcl._name == dc._name: return dc if sm_name in cl.virtuals: return dc return None
def __init__(self, class_name, statement, recurs): self.ident = class_name self.recurs = recurs self.protos = [] self.vt = None self.inst_vt = None self.non_mangled = [] # Ajoute aux membres les fcts qui recoivent une instance de l'objet en first param self.check_first_param(statement) # Mangling et save des membres self.members = [] self.add_legacy_fcts() if hasattr(statement, 'members'): for m in statement.members: if isinstance(m, cnorm.nodes.BlockStmt): for i in m.body: if (i._name == 'init'): self.add_new_proto(i) self.add_self_param(i) self.non_mangled.append(deepcopy(i)) i.saved_name = i._name i._name = mangler.muckFangle(i, class_name) self.members.append(i) else: if (m._name == 'init'): self.add_new_proto(m) self.add_self_param(m) self.non_mangled.append(deepcopy(m)) m.saved_name = m._name m._name = mangler.muckFangle(m, class_name) self.members.append(m) # Save des virtuals self.virtuals = {} if hasattr(statement, 'virtuals'): for v in statement.virtuals: if isinstance(v, cnorm.nodes.BlockStmt): for item in v.body: self.add_self_param(item) item.saved_name = item._name self.virtuals[item._name] = item else: self.add_self_param(v) v.saved_name = v._name self.virtuals[v._name] = v # Mangling et save des non membres self.decls = [] self.decls_vars = [] for d in statement.body: if isinstance(d, cnorm.nodes.BlockStmt): for i in d.body: i.saved_name = i._name i._name = mangler.muckFangle(i, class_name) if not isinstance(i._ctype, cnorm.nodes.FuncType): self.decls_vars.append(i) tmp = deepcopy(i) tmp._ctype._storage = 4 self.decls.append(tmp) else: self.decls.append(i) else: d.saved_name = d._name d._name = mangler.muckFangle(d, class_name) if not isinstance(d._ctype, cnorm.nodes.FuncType): self.decls_vars.append(d) tmp = deepcopy(d) tmp._ctype._storage = 4 self.decls.append(tmp) else: self.decls.append(d) self.add_alloc_proto() self.get_inheritance()