Exemplo n.º 1
0
        public static void Compile(ParserContext parser, ByteBuffer buffer, BaseMethodReference baseMethodReference, bool outputUsed)
        {
            ByteCodeCompiler.EnsureUsed(baseMethodReference, outputUsed);
            int baseClassId = baseMethodReference.ClassToWhichThisMethodRefers.ClassID;

            buffer.Add(
                baseMethodReference.DotToken,
                OpCode.PUSH_FUNC_REF,
                baseMethodReference.FunctionDefinition.FunctionID,
                1, // instance method
                0);
        }
Exemplo n.º 2
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, FunctionCall funCall, bool outputUsed)
        {
            bool argCountIsNegativeOne       = false;
            FunctionDefinition ownerFunction = funCall.Owner as FunctionDefinition;

            if (ownerFunction != null &&
                ownerFunction.NameToken.Value == "_LIB_CORE_invoke" &&
                ownerFunction.FileScope.CompilationScope.Dependencies.Length == 0)
            {
                argCountIsNegativeOne = true;
            }

            Expression root = funCall.Root;

            if (root is FunctionReference)
            {
                FunctionReference  verifiedFunction = (FunctionReference)root;
                FunctionDefinition fd = verifiedFunction.FunctionDefinition;

                if (parser.InlinableLibraryFunctions.Contains(fd))
                {
                    CompileInlinedLibraryFunctionCall(bcc, parser, buffer, funCall, fd, outputUsed);
                }
                else
                {
                    bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                    if (fd.Owner is ClassDefinition)
                    {
                        ClassDefinition cd = (ClassDefinition)fd.Owner;
                        if (fd.Modifiers.HasStatic)
                        {
                            buffer.Add(
                                funCall.ParenToken,
                                OpCode.CALL_FUNCTION,
                                (int)FunctionInvocationType.STATIC_METHOD,
                                funCall.Args.Length,
                                fd.FunctionID,
                                outputUsed ? 1 : 0,
                                cd.ClassID);
                        }
                        else
                        {
                            buffer.Add(
                                funCall.ParenToken,
                                OpCode.CALL_FUNCTION,
                                (int)FunctionInvocationType.LOCAL_METHOD,
                                funCall.Args.Length,
                                fd.FunctionID,
                                outputUsed ? 1 : 0,
                                cd.ClassID,
                                verifiedFunction.FunctionDefinition.MemberID);
                        }
                    }
                    else
                    {
                        // vanilla function
                        buffer.Add(
                            funCall.ParenToken,
                            OpCode.CALL_FUNCTION,
                            (int)FunctionInvocationType.NORMAL_FUNCTION,
                            funCall.Args.Length,
                            fd.FunctionID,
                            outputUsed ? 1 : 0,
                            0);
                    }
                }
            }
            else if (root is DotField)
            {
                DotField   ds           = (DotField)root;
                Expression dotRoot      = ds.Root;
                int        globalNameId = parser.GetId(ds.FieldToken.Value);
                bcc.CompileExpression(parser, buffer, dotRoot, true);
                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                int localeId = parser.GetLocaleId(ds.Owner.FileScope.CompilationScope.Locale);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.FIELD_INVOCATION,
                    funCall.Args.Length,
                    0,
                    outputUsed ? 1 : 0,
                    globalNameId,
                    localeId);
            }
            else if (root is BaseMethodReference)
            {
                BaseMethodReference bmr = (BaseMethodReference)root;
                FunctionDefinition  fd  = bmr.ClassToWhichThisMethodRefers.GetMethod(bmr.FieldToken.Value, true);
                if (fd == null)
                {
                    throw new ParserException(bmr.DotToken, "This method does not exist on any base class.");
                }

                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.LOCAL_METHOD,
                    funCall.Args.Length,
                    fd.FunctionID,
                    outputUsed ? 1 : 0,
                    bmr.ClassToWhichThisMethodRefers.ClassID,
                    -1);
            }
            else
            {
                bcc.CompileExpression(parser, buffer, root, true);
                bcc.CompileExpressionList(parser, buffer, funCall.Args, true);
                buffer.Add(
                    funCall.ParenToken,
                    OpCode.CALL_FUNCTION,
                    (int)FunctionInvocationType.POINTER_PROVIDED,
                    argCountIsNegativeOne ? -1 : funCall.Args.Length,
                    0,
                    outputUsed ? 1 : 0,
                    0);
            }
        }