Esempio n. 1
0
def fill_constructor(constructor: nodes.ConstructorImplementation, klass: nodes.Class,
                     vtable_init_mangler: mangler.Mangler, _this, _override_table: dict):
    inner_vtable_init_for_virtuality = [virtual for virtual in klass._ctype.fields if
                                        (type(virtual) is nodes.Method or type(virtual) is nodes.Destructor) and
                                        virtual.accessibility.virtual is True]
    inner_vtable_init_for_virtuality_stringified = '\n'.join(["vtable->{0} = &{1};".format(
        vtable_init_mangler.callable().params([_this] + virtual._ctype._params).type(
            virtual._ctype._identifier).name(virtual._name).mangle(),
        vtable_init_mangler.virtual().params([_this] + virtual._ctype._params).name(virtual._name).type(
            virtual._ctype._identifier).mangle()
    ) for virtual in inner_vtable_init_for_virtuality])

    _overriding_table = []
    if len(klass.parents):
        for name, override in _override_table.items():
            for _override in override:
                if _override["pre"] is True:
                    _overriding_table.insert(0, "vtable->{0} = &{1};".format(
                        '___' + '___'.join([str(len(n)) + n for n in _override['name']]) + '__8callable__' + str(
                            len(name)) + name,
                        vtable_init_mangler.callable().name(name).mangle()
                    ))
                else:
                    _overriding_table.insert(0, "(*(this->{0}))->{1} = &{2};".format(
                        _override['vtable'],
                        '___' + '___'.join([str(len(n)) + n for n in _override['name']]) + '__8callable__' + str(
                            len(name)) + name,
                        vtable_init_mangler.callable().name(name).mangle()
                    ))
    constructor.body.body = kooc.Kooc().parse(
        "int main() {" + inner_vtable_init_for_virtuality_stringified + '\n'.join(_overriding_table) + "}").body[
                                0].body.body + constructor.body.body
    pass
Esempio n. 2
0
def kooc_resolution(self: nodes.MethodImplementation, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler,
                    parents: list):
    if hasattr(self, 'virtual'):
        self._name = _mangler.virtual().name(self._name).mangle()
        _callable = (kooc.Kooc().parse("""int main() {
            int* vtable = ((void*)this) - 8;
            return (double)((*vtable)->""" + _mangler.callable().mangle() + """)(""" + ', '.join(
            [p._name for p in self._ctype._params]) + """);
        }""")).body[0]
        _callable._name = _mangler.callable().mangle()
        _callable._ctype._params = self._ctype._params
        _callable._ctype._identifier = self._ctype._identifier
        _callable.body.body[1].expr.params[0]._identifier = self._ctype._identifier
        _callable.body.body[0]._ctype._identifier = '__6vtable' + self._ctype._params[0]._ctype._identifier
        return [self, _callable]
    else:
        self._name = _mangler.callable().name(self._name).mangle()
        return self
Esempio n. 3
0
def make_vtable(klass: nodes.Class, name: str, _mangler: mangler.Mangler, _this: cnorm.nodes.Decl, parents: list, ast):
    vtable_mangler = copy.deepcopy(_mangler)
    vtable_mangler.container(klass.class_name)
    res = cnorm.nodes.Decl('', cnorm.nodes.ComposedType('__6vtable' + name))
    res._ctype.fields = []
    res._ctype._specifier = 1
    res._ctype._attr_composed = ['__attribute__((packed)) ']
    for declaration in klass._ctype.fields:
        if type(declaration) is not nodes.Attribute and declaration.accessibility.virtual is True:
            _declaration_pointer = cnorm.nodes.Decl(
                vtable_mangler.name(declaration._name).type(declaration._ctype._identifier).params(
                    declaration._ctype._params).callable().mangle(),
                cnorm.nodes.PrimaryType(declaration._ctype._identifier))
            _declaration_pointer._ctype._decltype = cnorm.nodes.PointerType()
            _declaration_pointer._ctype._decltype._decltype = cnorm.nodes.ParenType(
                [_this] + declaration._ctype._params)
            res._ctype.fields.append(_declaration_pointer)
    if len(parents):
        self = parents[0]
        super_supers = []
        for parent_name in self.parents:
            _parent = ast.search_in_tree(lambda super, _parents:
                                         super if type(super) is nodes.Class
                                                  and super.class_name == parent_name.value
                                                  and _parents == parent_name.scope else None)
            if _parent is None:
                print("error: super class of " + self.class_name + " named " + '@'.join(
                    parent_name.scope + [parent_name.value]) + " doesn't exist", file=sys.stderr)
                exit(-1)
            super_supers.append(_parent)
        _super_this = cnorm.nodes.Decl('', cnorm.nodes.PrimaryType(
            _mangler.name(klass.class_name).type_definition().mangle()))
        res._ctype.fields = \
            make_vtable(parents[0], _mangler.class_definition().name(klass.class_name).mangle(), _mangler, _super_this,
                        super_supers, ast)[0]._ctype.fields + res._ctype.fields
    _typedef = cnorm.nodes.Decl('__6vtable' + _mangler.type_definition().name(klass.class_name).mangle(),
                                cnorm.nodes.ComposedType(res._ctype._identifier))
    _typedef._ctype._decltype = cnorm.nodes.PointerType()
    _typedef._ctype._specifier = 1
    _typedef._ctype._storage = 2

    return [res, _typedef]
Esempio n. 4
0
def kooc_resolution(self: cnorm.nodes.Decl, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents):
    res = node.Node.kooc_resolution(self, ast, _mangler, parents)
    if res is not None:
        if hasattr(res, '_ctype'):
            if res._ctype._storage == 0:
                _mangler.type(res._ctype._identifier).variable()
                if hasattr(res._ctype, '_params'):
                    _mangler.callable().params(res._ctype._params)
            elif res._ctype._storage == 2 or res._ctype._storage == 1:
                _mangler.type_definition()
            if '@' in res._ctype._identifier:
                res._ctype._identifier = identifier_mangling(res._ctype._identifier)
        self._name = _mangler.name(self._name).mangle()
    return res
Esempio n. 5
0
def kooc_resolution(self: nodes.Class, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents):
    new_mangler = copy.copy(_mangler)
    new_mangler.enable()
    new_mangler.container(self._ctype._identifier)

    global nm
    nm.push(nodes.Destructor, lambda destructor: False)
    nm.push(nodes.Constructor, lambda destructor: False)
    nm.push(nodes.Method, lambda destructor: False)

    supers = []
    for parent_name in self.parents:
        _parent = ast.search_in_tree(lambda super, _parents:
                                     super if type(super) is nodes.Class
                                              and super.class_name == parent_name.value
                                              and _parents == parent_name.scope else None)
        if _parent is None:
            print("error: super class of " + self.class_name + " named " + '@'.join(
                parent_name.scope + [parent_name.value]) + " doesn't exist", file=sys.stderr)
            exit(-1)
        supers.append(_parent)

    self._ctype._identifier = _mangler.name(self._ctype._identifier).class_definition().mangle()
    _this = cnorm.nodes.Decl('', cnorm.nodes.PrimaryType(_mangler.type_definition().mangle()))
    vtable = make_vtable(self, self._ctype._identifier, _mangler, _this, supers, ast)

    _typedef = cnorm.nodes.Decl(_mangler.type_definition().mangle(), cnorm.nodes.ComposedType(self._ctype._identifier))
    _typedef._ctype._decltype = cnorm.nodes.PointerType()
    _typedef._ctype._specifier = 1
    _typedef._ctype._storage = 2

    method_mangler = copy.copy(new_mangler)
    methods_declaration = []
    for method in self._ctype.fields:
        if type(method) is nodes.Method:
            for decl in method._ctype._params:
                decl._ctype.kooc_resolution(ast, _mangler, parents)
            method._ctype._params = [_this] + method._ctype._params
            if method.accessibility.virtual is True:
                virtual = copy.deepcopy(method)
                method_mangler._symtype = "__7virtual"
                virtual._name = method_mangler.name(method._name).params(virtual._ctype._params).mangle()
                methods_declaration.append(virtual)
            method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle()
            methods_declaration.append(method)
        elif type(method) is nodes.Constructor:
            newer = copy.deepcopy(method)
            method._ctype._params = [_this, cnorm.nodes.Decl('', cnorm.nodes.PrimaryType(
                vtable[1]._name))] + method._ctype._params
            method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle()
            newer._name = method_mangler.name("new").params(newer._ctype._params).mangle()
            newer._ctype._identifier = _typedef._name;
            methods_declaration.append(method)
            methods_declaration.append(newer)
        elif type(method) is nodes.Destructor:
            method._ctype._params = [_this] + method._ctype._params
            newer = copy.deepcopy(method)
            if method.accessibility.virtual is True:
                virtual = copy.deepcopy(method)
                method_mangler._symtype = "__7virtual"
                virtual._name = method_mangler.name(method._name).mangle()
                methods_declaration.append(virtual)
            method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle()
            newer._name = method_mangler.name("delete").mangle()
            methods_declaration.append(method)
            methods_declaration.append(newer)

    self._ctype.fields = sub_resolution(self._ctype.fields, ast, new_mangler, parents)
    for _super in reversed(supers):
        res = copy.deepcopy(_super).kooc_resolution(ast, _mangler, parents)
        self._ctype.fields = res[-1]._ctype.fields + self._ctype.fields
        self._ctype.fields.insert(0, cnorm.nodes.Decl(
            '__6vtable__' + str(len(self.class_name)) + self.class_name + '__' + str(
                len(_super.class_name)) + _super.class_name, cnorm.nodes.PrimaryType(res[1]._name)))
        self._ctype.fields[0]._ctype._decltype = cnorm.nodes.PointerType()
    if len(supers):
        self._ctype.fields = self._ctype.fields[1:]

    nm.pop(nodes.Destructor)
    nm.pop(nodes.Constructor)
    nm.pop(nodes.Method)

    return [_typedef, vtable[1]] + methods_declaration + [vtable[0]] + [self]