def kc_add_class(self, current_block, name_node, inheritance_list, class_block): parents = [] if hasattr(inheritance_list, "parents"): parents = inheritance_list.parents class_name = self.value(name_node) ktypes = current_block.ref.ktypes if class_name in ktypes: raise KParsingError("Class re-opening not supported") knodes.KcClass.init_from_blockstmt(class_block, class_name) klass = class_block # add parents for parent_name in parents: if parent_name not in ktypes: raise KParsingError("Unknown class parent type '%s'" % parent_name) klass.parents.append(parent_name) ktypes[class_name] = ref(klass) current_block.ref.body.append(klass) # C type for class: # ==== typedef kc_{class}_interface {class}; ==== class_interface_struct_ctype = nodes.ComposedType('kc_' + class_name + '_interface') class_interface_struct_ctype._specifier = nodes.Specifiers.STRUCT class_interface_struct_ctype._storage = nodes.Storages.TYPEDEF klass.typedef = nodes.Decl(class_name, class_interface_struct_ctype) current_block.ref.types[class_name] = ref(klass.typedef) return True
def build_instance_struct(self, klass): def add_decl_fields_from_group(group_holder, fields_holder): for name in sorted(group_holder.keys()): for decl in group_holder[name]: decl_no_assign = copy.deepcopy(decl) if hasattr(decl_no_assign, '_assign_expr'): delattr(decl_no_assign, '_assign_expr') fields_holder.append(decl_no_assign) instance_struct_ctype = nodes.ComposedType('kc_' + klass.name + '_instance') instance_struct_ctype._specifier = nodes.Specifiers.STRUCT instance_struct_ctype._attr_composed = ['__attribute__((packed))'] instance_struct_ctype.fields = [] # assemble struct fields (instance member variables) for parent_name in klass.parents: members = klass.parents_members[parent_name] add_decl_fields_from_group(members, instance_struct_ctype.fields) add_decl_fields_from_group(klass.members, instance_struct_ctype.fields) return nodes.Decl('', instance_struct_ctype)
def add_enum(self, lspec, n, block): ctype = nodes.ComposedType(self.value(n)) if lspec.ctype is not None: ctype._storage = lspec.ctype._storage ctype._specifier = lspec.ctype._specifier lspec.ctype = ctype if hasattr(block, 'list'): lspec.ctype.enums = block.list return True
def add_composed(self, lspec, n, block): ctype = nodes.ComposedType(self.value(n)) if lspec.ctype is not None: ctype._storage = lspec.ctype._storage ctype._specifier = lspec.ctype._specifier if hasattr(lspec.ctype, '_attr_composed'): ctype._attr_composed = lspec.ctype._attr_composed lspec.ctype = ctype if hasattr(block, 'body'): lspec.ctype.fields = block.body return True
def build_interface_struct(self, klass): interface_struct_ctype = nodes.ComposedType('kc_' + klass.name + '_interface') interface_struct_ctype._specifier = nodes.Specifiers.STRUCT interface_struct_ctype._attr_composed = ['__attribute__((packed))'] interface_struct_ctype.fields = [] # meta field meta_ctype = nodes.PrimaryType('kc_' + klass.name + '_metadata') meta_ctype.push(nodes.PointerType()) interface_struct_ctype.fields.append(nodes.Decl('meta', meta_ctype)) # instance field instance_ctype = nodes.PrimaryType('kc_' + klass.name + '_instance') interface_struct_ctype.fields.append(nodes.Decl('instance', instance_ctype)) return nodes.Decl('', interface_struct_ctype)
def build_vtable_struct(self, klass): def add_decl_fields_from_group(group_holder, fields_holder): for name in sorted(group_holder.keys()): for decl in group_holder[name]: fields_holder.append(decl) vtable_struct_ctype = nodes.ComposedType('kc_' + klass.name + '_vtable') vtable_struct_ctype._specifier = nodes.Specifiers.STRUCT vtable_struct_ctype._attr_composed = ['__attribute__((packed))'] vtable_struct_ctype.fields = [] # add virtuals from class's parents for parent_name in klass.parents: virtuals = klass.parents_virtuals[parent_name] add_decl_fields_from_group(virtuals, vtable_struct_ctype.fields) # add virtuals from current class add_decl_fields_from_group(klass.virtuals, vtable_struct_ctype.fields) return nodes.Decl('', vtable_struct_ctype)
def build_metadata_struct(self, klass): struct_ctype = nodes.ComposedType('kc_' + klass.name + '_metadata') struct_ctype._specifier = nodes.Specifiers.STRUCT struct_ctype._attr_composed = ['__attribute__((packed))'] struct_ctype.fields = [] # class name cname_ctype = nodes.PrimaryType('char') cname_ctype.push(nodes.PointerType()) struct_ctype.fields.append(nodes.Decl('name', cname_ctype)) # inheritance list inhlist_ctype = nodes.PrimaryType('char') inhlist_ctype.push(nodes.PointerType()) struct_ctype.fields.append(nodes.Decl('inheritance_list', inhlist_ctype)) # vtable vtable_ctype = nodes.PrimaryType('kc_' + klass.name + '_vtable') struct_ctype.fields.append(nodes.Decl('vtable', vtable_ctype)) return nodes.Decl('', struct_ctype)
def add_cl(self, ast, ret): from cnorm import nodes from copy import deepcopy global clist global mlist global vlist if ret.mname in mlist or ret.mname in clist: print_error("Error module or class already declared : " + ret.mname) return False if not ret.mname in clist: clist[ret.mname] = [] for item in ret.node.body: clist[ret.mname].append(mangle(item, ret.mname, "C")) ast.node.body.extend(ret.node.body) test = "<class \'cnorm.nodes.FuncType\'>" private_var = [ item for item in ret.private.body if str(type(item._ctype)) != test ] private_func = [ item for item in ret.private.body if str(type(item._ctype)) == test ] if not hasattr(slist, ret.mname): slist[ret.mname] = [] for item in private_var: slist[ret.mname].append(mangle(item, ret.mname, "CM")) st = nodes.Decl(ret.mname) st._ctype = nodes.ComposedType(ret.mname) st._ctype._specifier = 1 st._ctype._storage = 2 st._ctype.fields = private_var ast.node.body.append(st) if not hasattr(vlist, ret.mname): vlist[ret.mname] = [] parse = Declaration() nod = parse.parse("struct " + ret.mname + " * self;") for item in private_func: vlist[ret.mname].append(mangle(item, ret.mname, "CM")) item._ctype._params.append(nod.body[0]) ntmp = deepcopy(item) ast.node.body.append(ntmp) item._name = "(*" + item._name + ")" st = nodes.Decl("vtable_" + ret.mname) st._ctype = nodes.ComposedType("vtable_" + ret.mname) st._ctype._specifier = 1 st._ctype._storage = 2 st._ctype.fields = private_func ast.node.body.append(st) parse = Declaration() cl = ret.mname vt = "vtable_" + cl free = "void delete() { void *fr = (void*)(self - sizeof(struct " + vt + ")); free(fr);}" d_free = parse.parse(free) m_free = mangle(d_free.body[0], cl, "CM") vlist[cl].append(m_free) free = "void delete(struct " + cl + " *self) { void *fr = (void*)( ((struct " + vt + " *)(self)) - 1); free(fr);}" d_free = parse.parse(free) d_free.body[0]._name = m_free["mangle"] ast.node.body.append(d_free.body[0]) tmp = deepcopy(d_free) tmp.body[0]._name = "(*" + tmp.body[0]._name + ")" tmp.body[0].body = None st._ctype.fields.append(tmp.body[0]) ptr_func = "" for item in vlist[cl]: ptr_func += "ptr->" + item["mangle"] + " = &" + item["mangle"] + ";" dl = "struct " + cl + " *alloc" code = vt + " *ptr = (struct " + vt + " *) malloc(sizeof(struct " + cl + ") + sizeof(struct " + vt + "));" \ + ptr_func + "return (struct " + cl + " *)(ptr + 1);" alloc = dl + "(){" + code + "}" d_alloc = parse.parse(alloc) m_alloc = mangle(d_alloc.body[0], cl, "C") clist[cl].append(m_alloc) ast.node.body.append(d_alloc.body[0]) dn = "struct " + cl + " *new" code = "struct " + cl + " *ptr = " + m_alloc["mangle"] + "(); return ptr;" new = dn + "(){" + code + "}" d_new = parse.parse(new) m_new = mangle(d_new.body[0], ret.mname, "C") clist[cl].append(m_new) ast.node.body.append(d_new.body[0]) return True