Exemplo n.º 1
0
        public override RegisterLabelContext Visit(MethodCall methodCall)
        {
            var objectExpr  = Visit(methodCall.IdExpr);
            var objectClass = _globalState.NameToClass[objectExpr.Type.GetText()];

            var(method, methodNum) = objectClass.Methods[methodCall.Id];
            var selfType = method.Args.Last().Type;

            if (objectClass.Id != selfType.GetText())
            {
                var nextRegister = _state.NewRegister;
                _llvmGenerator.Emit(
                    $"{nextRegister} = bitcast %{objectClass.Id}* {objectExpr.Register} to %{selfType.GetText()}*");
                objectExpr.Register = nextRegister;
                objectExpr.Type     = selfType;
            }

            string newRegister1 = _state.NewRegister, newRegister2 = _state.NewRegister,
                   newRegister3 = _state.NewRegister, newRegister4 = _state.NewRegister;

            _llvmGenerator.Emit($"{newRegister1} = getelementptr %{selfType.GetText()}, %{selfType.GetText()}* " +
                                $"{objectExpr.Register}, i32 0, i32 0");
            _llvmGenerator.Emit(
                $"{newRegister2} = load %{selfType.GetText()}_vtable*, %{selfType.GetText()}_vtable** {newRegister1}");
            _llvmGenerator.Emit($"{newRegister3} = getelementptr %{selfType.GetText()}_vtable, %{selfType.GetText()}_vtable*" +
                                $" {newRegister2}, i32 0, i32 {methodNum}");
            _llvmGenerator.Emit($"{newRegister4} = load {AstToLlvmString.FunctionalType(method)}, " +
                                $"{AstToLlvmString.FunctionalType(method)}* {newRegister3}");

            return(VisitFunctionCall(
                       new FunCall
            {
                Id = "",
                Exprs = methodCall.Exprs
            },
                       objectExpr,
                       new FunctionDef
            {
                Id = newRegister4,
                Type = method.Type,
                Args = method.Args
            }));
        }
Exemplo n.º 2
0
        public void GenerateVTable(ClassDef @class)
        {
            _llvmGenerator.Emit($"%{@class.Id}_vtable = type " + "{");

            var isFirst = true;

            @class.Methods.Values.ToList().ForEach(method =>
            {
                var toEmit = "";
                if (!isFirst)
                {
                    toEmit = ",";
                }

                toEmit += AstToLlvmString.FunctionalType(method.Item1);
                _llvmGenerator.Emit(toEmit);

                isFirst = false;
            });

            _llvmGenerator.Emit("}");

            _llvmGenerator.Emit($"@{@class.Id}_vtable_ptrs = global %{@class.Id}_vtable " + "{");

            isFirst = true;
            @class.Methods.Values.ToList().ForEach(method =>
            {
                var toEmit = "";
                if (!isFirst)
                {
                    toEmit = ",";
                }

                toEmit += AstToLlvmString.FunctionalType(method.Item1);
                toEmit += $" @{method.Item1.Id}";
                _llvmGenerator.Emit(toEmit);

                isFirst = false;
            });

            _llvmGenerator.Emit("}");
        }