protected virtual Expression VisitInvoke(InvokeExpression node)
 {
     Visit(node.TargetType);
     Visit(node.Method);
     node.Arguments.ForEach(arg => Visit(arg.Value));
     return(node);
 }
        public static IMethodInfo GetMethod(this InvokeExpression invokeExpr, SemanticContext context)
        {
            var parts = invokeExpr.MethodName.Parts.ToInvertedStack();

            TypeDefinition type;

            if (!context.TypeRegistry.TrySearch(parts, out type))
            {
                throw new SemanticException("Can't find method by identifier: {0}", invokeExpr.MethodName);
            }

            // todo: implement member chaining

            var methodName = parts.Pop();
            var types      = invokeExpr.Arguments
                             .Select(x => TypeInference.InferType(x.Value, context))
                             .ToArray(invokeExpr.Arguments.Count);

            var method = type.GetMethod(methodName, types);

            if (method == null)
            {
                throw new SemanticException("Can't find method by identifier: {0}", invokeExpr.MethodName);
            }

            if (method.DeclaringType.Assembly.Equals(context.TypeDefinition.Assembly))
            {
                return(method);
            }

            return(MethodFactory.GetMethodReference(method));
        }
Exemple #3
0
        /// <summary>
        /// To RegExp format
        /// <example>/start(.*?)end/gi</example>
        /// </summary>
        /// <param name="invoke"></param>
        /// <returns></returns>
        public static string ToRegExp(this InvokeExpression invoke)
        {
            if (invoke.InvokeType != InvokeType.RegExpCompile || invoke.Parameters.Count < 1 ||
                !(invoke.Parameters[0] is ConstantExpression constant) || !(constant.Variant is TjsString tStr))
            {
                throw new ArgumentException("The Expression is not a RegExp");
            }

            var regex = tStr.StringValue;

            if (!regex.StartsWith("//"))
            {
                return(regex); //TODO: maybe wrong but who cares
            }

            StringBuilder sb = new StringBuilder();

            sb.Append('/');
            var count = 0;

            while (regex[2 + count] != '/')
            {
                count++;
            }

            sb.Append(regex.Substring(2 + count + 1)).Append('/');

            if (count > 0)
            {
                sb.Append(regex.Substring(2, count));
            }

            return(sb.ToString());
        }
Exemple #4
0
        public virtual void Visit(InvokeExpression exp)
        {
            exp.AddressEpr.AcceptVisitor(this);

            if (exp.HasArguments)
            {
                foreach (var argument in exp.Arguments)
                {
                    argument.AcceptVisitor(this);
                }
            }
        }
Exemple #5
0
        protected virtual Expression VisitInvoke(InvokeExpression node)
        {
            var expression = Visit(node.Expression);
            var arguments  = VisitExpressionList(node.Arguments);

            if (!ReferenceEquals(expression, node.Expression) || !ReferenceEquals(arguments, node.Arguments))
            {
                return(new InvokeExpression(expression, arguments));
            }

            return(node);
        }
Exemple #6
0
        Expression ParseMemberExpression()
        {
            Expression exp;

            if (Accept(TokenType.SymbolPeriod))
            {
                exp = new DirectMemberAccessExpression(null, Expect(TokenType.Identifier).Value.ToString());
            }
            else
            {
                exp = ParsePrimaryExpression();
            }
            while (true)
            {
                if (Accept(TokenType.SymbolPeriod))
                {
                    exp = new DirectMemberAccessExpression(exp, Expect(TokenType.Identifier).Value.ToString());
                }
                else if (Accept(TokenType.SymbolOpenBracket))
                {
                    exp = new IndirectMemberAccessExpression(exp, ParseExpression());
                    Expect(TokenType.SymbolCloseBracket);
                }
                else if (Accept(TokenType.SymbolOpenParenthesis))
                {
                    bool inheritArgs = false;
                    List <InvocationArgument> arguments = new List <InvocationArgument>();
                    if (!Accept(TokenType.SymbolCloseParenthesis))
                    {
                        if (Accept(TokenType.SymbolTriplePeriod))
                        {
                            inheritArgs = true;
                        }
                        else
                        {
                            arguments.Add(ParseInvocationArgument());
                            while (Accept(TokenType.SymbolComma))
                            {
                                arguments.Add(ParseInvocationArgument());
                            }
                        }
                        Expect(TokenType.SymbolCloseParenthesis);
                    }
                    exp = new InvokeExpression(exp, arguments, inheritArgs);
                }
                else
                {
                    break;
                }
            }
            return(exp);
        }
Exemple #7
0
        public void ParseInvokeExpressionWithSplats()
        {
            IExpression expression = ParseExpression("DoSomething(3, pars...)");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(InvokeExpression));

            InvokeExpression invexp = (InvokeExpression)expression;

            Assert.AreEqual("DoSomething", invexp.Name);
            Assert.AreEqual(2, invexp.Arguments.Count);
            Assert.IsInstanceOfType(invexp.Arguments.First(), typeof(ConstantExpression));
        }
        public void EvaluateInvokeExpression()
        {
            InvokeExpression invoke    = new InvokeExpression("foo", new IExpression[] { new ConstantExpression(1) });
            Machine          machine   = new Machine();
            Procedure        procedure = new Procedure("foo", new string[] { "x" }, new ReturnCommand(new NameExpression("x")), machine);

            machine.Environment.SetValue("foo", procedure);

            object result = invoke.Evaluate(machine.Environment);

            Assert.IsNotNull(result);
            Assert.AreEqual(1, result);
        }
Exemple #9
0
        StatementBlock TranslateInvoke(InvokeExpression e)
        {
            var function = Assert.IsType <TypeReference.FunctionTypeCase>(e.Function.Type()).Item;

            var args = e.Args.Select(TranslateExpression).ToArray();

            if (e.Function is Expression.ParameterCase variable && this.ActiveLocalFunctions.TryGetValue(variable.Item.Id, out var localFunction))
            {
                var call = CallLocalFunction(localFunction, args.Select(a => a.Instr()));
                return(StatementBlock.Concat(
                           args.Append(StatementBlock.Expression(localFunction.Method.ReturnType, call))
                           ));
            }
Exemple #10
0
        public void ParseInvokeExpression()
        {
            IExpression expression = ParseExpression("Factorial(3)");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(InvokeExpression));

            InvokeExpression invexp = (InvokeExpression)expression;

            Assert.AreEqual("Factorial", invexp.Name);
            Assert.AreEqual(1, invexp.Arguments.Count);
            Assert.IsInstanceOfType(invexp.Arguments.First(), typeof(ConstantExpression));
        }
        private bool NeedStackBalancing(InvokeExpression node, IMethodInfo method)
        {
            if (!node.IsStatementExpression)
            {
                return(false);
            }
            if (method.ReturnType.Equals(KnownType.Void))
            {
                return(false);
            }

            return(true);
        }
Exemple #12
0
            public override void Visit(InvokeExpression exp)
            {
                exp.AddressEpr.AcceptVisitor(this);
                cb.Write('(');
                if (exp.HasArguments)
                {
                    foreach (var argument in exp.Arguments)
                    {
                        argument.AcceptVisitor(this);
                    }
                }

                cb.Write(')');
            }
Exemple #13
0
 private static void WriteInvokeExpression(InvokeExpression node, IndentedTextWriter writer)
 {
     if (node.Function is UnaryOperatorFunctionSymbol)
     {
         WriteUnaryOperatorFunctionInvocationExpression(node, writer);
     }
     else if (node.Function is BinaryOperatorFunctionSymbol)
     {
         WriteBinaryOperatorFunctionInvocationExpression(node, writer);
     }
     else
     {
         WriteFunctionInvocationExpression(node, writer);
     }
 }
Exemple #14
0
        public override void Visit(InvokeExpression exp)
        {
            StartElement("callExpression");
            exp.AddressEpr.AcceptVisitor(this);
            if (exp.Arguments != null)
            {
                StartElement("parameters");
                foreach (var argument in exp.Arguments)
                {
                    argument.AcceptVisitor(this);
                }

                EndElement();
            }
            EndElement();
        }
        public void VisitInvokeExpression(InvokeExpression node)
        {
            foreach (var arg in node.Arguments)
            {
                arg.Accept(this);
            }

            var method = node.GetMethod(_context);

            _emitter.Emit(OpCodes.Call, method);

            if (NeedStackBalancing(node, method))
            {
                _emitter.Emit(OpCodes.Pop);
            }
        }
Exemple #16
0
        public void EvaluateInvokeExpression()
        {
            ICommand body     = new ReturnCommand(new VariableExpression("x"));
            Function function = new Function(new string[] { "x" }, body);

            BindingEnvironment environment = new BindingEnvironment();

            environment.SetValue("foo", function);

            IExpression expression = new InvokeExpression("foo", new IExpression[] { new ConstantExpression(1) });

            object result = expression.Evaluate(environment);

            Assert.IsNotNull(result);
            Assert.AreEqual(1, result);
        }
Exemple #17
0
        public MethodResolution(MethodInfo methodInfo, Closure closure, InvokeExpression callAst)
        {
            MethodInfo = methodInfo;
            Closure = closure;
            CallAst = callAst;
            Result = null;

            PassesComplete = null;
            Target = new StronglyTypedAstBuilder(closure).Visit(callAst.Target);
            FormalArgs = new List<Type>(MethodInfo.GetParameters().Select(p => p.ParameterType));
            RealArgs = new List<Expression>(callAst.Args.Select(ast => ast is LambdaExpression ?
                new StronglyTypedAstBuilder(closure).VisitLambda((LambdaExpression)ast, null, true) :
                new StronglyTypedAstBuilder(closure).Visit(ast)));
            InferenceCache = new Dictionary<Type, Type>();
            Array.ForEach(MethodInfo.GetGenericArguments(), t => InferenceCache.Add(t, null));
        }
Exemple #18
0
        private static void WriteUnaryOperatorFunctionInvocationExpression(InvokeExpression node, IndentedTextWriter writer)
        {
            if (experimental)
            {
                var function   = (UnaryOperatorFunctionSymbol)node.Function;
                var precedence = function.OperatorDescriptor.Precedence;

                writer.WritePunctuation(function.OperatorDescriptor.Operator);
                var childExpression = node.Arguments.ToArray()[0];
                if (childExpression is InvokeExpression ie && ie.Function is IOperatorFunctionSymbol opfs)
                {
                    writer.WriteNestedExpression(precedence, opfs.GetOperatorDescriptor().Precedence, childExpression);
                }
                else
                {
                    childExpression.WriteTo(writer);
                }
            }
        public virtual LinqExpression VisitInvoke(InvokeExpression call)
        {
            var resolved = ResolveMethod(null, call);
            if (resolved == null)
            {
                // Screw extension methods other than from Queryable and Enumerable
                resolved = ResolveMethod(typeof(Queryable), call);
                resolved = resolved ?? ResolveMethod(typeof(Enumerable), call);
            }

            if (resolved != null)
            {
                return resolved;
            }
            else
            {
                throw new NotSupportedException(call.ToString());
            }
        }
Exemple #20
0
        private IExpression ParseTermExpression()
        {
            if (this.TryParse(TokenType.Name, "new"))
            {
                return(ParseNewExpression());
            }

            IExpression expression = this.ParseSimpleTermExpression();

            while (this.TryParse(TokenType.Operator, ".") || this.TryParse(TokenType.Separator, "[", "("))
            {
                if (this.TryParse(TokenType.Operator, "."))
                {
                    this.lexer.NextToken();
                    string name = this.ParseName();
                    IList <IExpression> arguments = null;

                    if (this.TryParse(TokenType.Separator, "("))
                    {
                        arguments = this.ParseArgumentList();
                    }

                    expression = new DotExpression(expression, name, arguments);
                    continue;
                }

                if (this.TryParse(TokenType.Separator, "("))
                {
                    IList <IExpression> arguments = this.ParseArgumentList();
                    expression = new InvokeExpression(expression, arguments);
                    continue;
                }

                expression = new ArrayExpression(expression, this.ParseArrayArgumentList());
            }

            return(expression);
        }
        public void BlockProcess(DecompileContext context, Block block,
                                 Dictionary <int, Expression> exps)
        {
            if (block.Statements != null)
            {
                return;
            }

            if (block.From.Count > 1)
            {
                //get from.Output && from.Def
                var commonInput = block.From.Select(b => b.Output).Union(block.From.Select(b => b.Def)).GetIntersection();
                commonInput.IntersectWith(block.Input);
                //flag can be phi
                if (commonInput.Count > 0)
                {
                    foreach (var inSlot in commonInput)
                    {
                        //Generate Phi
                        var phi = new PhiExpression(inSlot);
                        //From must be sorted since we need first condition
                        if (block.From[0].Statements?.Last() is ConditionExpression condition)
                        {
                            phi.Condition = condition;
                            //var thenBlock = context.BlockTable[condition.JumpTo];
                            var elseBlock = context.BlockTable[condition.ElseTo];
                            //phi.ThenBranch = context.BlockFinalStates[trueBlock][inSlot];
                            phi.ThenBranch =
                                context.BlockFinalStates[block.From[0]]
                                [inSlot];     //if jump, use the state from the jump-from block
                            phi.ElseBranch = context.BlockFinalStates[elseBlock][inSlot];
                            //Next: Merge condition: if (v1) then v1 else v2 => v1 || v2 (infer v1 is bool)
                            if (phi.ThenBranch != phi.ElseBranch)
                            {
                                exps[inSlot] = phi;
                            }
                        }
                    }
                }
            }

            Expression retExp  = null;
            var        ex      = new Dictionary <int, Expression>(exps);
            var        flag    = ex.ContainsKey(Const.FlagReg) ? ex[Const.FlagReg] : null;
            var        expList = new List <IAstNode>();

            block.Statements = expList;
            InstructionData insData = null;

            for (var i = 0; i < block.Instructions.Count; i++)
            {
                ex[0] = Void;
                var ins = block.Instructions[i];
                insData = block.InstructionDatas[i];

                switch (ins.OpCode)
                {
                case OpCode.NOP:
                    break;

                case OpCode.CONST:
                {
                    var data     = (OperandData)ins.Data;
                    var constExp = new ConstantExpression(data.Variant);
                    ex[ins.GetRegisterSlot(0)] = constExp;
                }
                break;

                case OpCode.CL:
                {
                    ex[ins.GetRegisterSlot(0)] = null;
                }
                break;

                case OpCode.CCL:
                    break;

                case OpCode.CEQ:
                case OpCode.CDEQ:
                case OpCode.CLT:
                case OpCode.CGT:
                {
                    var      left  = ex[ins.GetRegisterSlot(0)];
                    var      right = ex[ins.GetRegisterSlot(1)];
                    BinaryOp op    = BinaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.CEQ:
                        op = BinaryOp.Equal;
                        break;

                    case OpCode.CDEQ:
                        op = BinaryOp.Congruent;
                        break;

                    case OpCode.CLT:
                        op = BinaryOp.LessThan;
                        break;

                    case OpCode.CGT:
                        op = BinaryOp.GreaterThan;
                        break;
                    }

                    var b = new BinaryExpression(left, right, op);
                    flag = b;
                }
                break;

                case OpCode.SETF:
                case OpCode.SETNF:
                {
                    var dst = ins.GetRegisterSlot(0);
                    switch (ins.OpCode)
                    {
                    case OpCode.SETF:
                        ex[dst] = flag;
                        break;

                    case OpCode.SETNF:
                        ex[dst] = flag.Invert();
                        break;
                    }
                }
                break;

                case OpCode.TT:
                {
                    flag = ex[ins.GetRegisterSlot(0)];
                }
                break;

                case OpCode.TF:
                {
                    flag = ex[ins.GetRegisterSlot(0)].Invert();
                }
                break;

                case OpCode.NF:
                {
                    flag = flag.Invert();
                }
                break;

                case OpCode.JF:
                case OpCode.JNF:
                {
                    bool jmpFlag = ins.OpCode == OpCode.JF;
                    expList.Add(new ConditionExpression(flag, jmpFlag)
                        {
                            JumpTo = ((JumpData)ins.Data).Goto.Line, ElseTo = ins.Line + 1
                        });
                }
                break;

                case OpCode.JMP:
                {
                    expList.Add(new GotoExpression {
                            JumpTo = ((JumpData)ins.Data).Goto.Line
                        });
                }
                break;

                case OpCode.CHS:
                case OpCode.INT:
                case OpCode.REAL:
                case OpCode.STR:
                case OpCode.NUM:
                case OpCode.OCTET:
                case OpCode.LNOT:
                case OpCode.INC:
                case OpCode.DEC:
                case OpCode.BNOT:
                case OpCode.TYPEOF:
                case OpCode.INV:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var dst     = ex[dstSlot];
                    var op      = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INC:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DEC:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.CHS:
                        op = UnaryOp.InvertSign;
                        break;

                    case OpCode.INT:
                        op = UnaryOp.ToInt;
                        break;

                    case OpCode.REAL:
                        op = UnaryOp.ToReal;
                        break;

                    case OpCode.STR:
                        op = UnaryOp.ToString;
                        break;

                    case OpCode.NUM:
                        op = UnaryOp.ToNumber;
                        break;

                    case OpCode.BNOT:
                        op = UnaryOp.BitNot;
                        break;

                    case OpCode.OCTET:
                        op = UnaryOp.ToByteArray;
                        break;

                    case OpCode.LNOT:
                        op = UnaryOp.Not;
                        break;

                    case OpCode.TYPEOF:
                        op = UnaryOp.TypeOf;
                        break;

                    case OpCode.INV:
                        op = UnaryOp.Invalidate;
                        break;
                    }

                    var u = new UnaryExpression(dst, op);
                    //ex[dstSlot] = u;
                    expList.Add(u);
                }
                break;

                case OpCode.INCPD:
                case OpCode.DECPD:
                case OpCode.TYPEOFD:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.Data.AsString();
                    var op   = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INCPI:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DECPI:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.TYPEOFD:
                        op = UnaryOp.TypeOf;
                        break;
                    }

                    //var u = new UnaryExpression(new IdentifierExpression(name), op) {Instance = ex[obj]};
                    var u = new UnaryExpression(new IdentifierExpression(name)
                        {
                            Instance = ex[obj]
                        }, op);
                    if (res != 0)     //copy to %res
                    {
                        ex[res] = u;
                    }

                    expList.Add(u);
                }
                break;

                case OpCode.INCPI:
                case OpCode.DECPI:
                case OpCode.TYPEOFI:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);
                    var op   = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INCPI:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DECPI:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.TYPEOFI:
                        op = UnaryOp.TypeOf;
                        break;
                    }

                    var u = new UnaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), op);
                    if (res != 0)     //copy to %res
                    {
                        ex[res] = u;
                    }

                    expList.Add(u);
                }
                break;

                case OpCode.INCP:
                case OpCode.DECP:
                    break;

                case OpCode.LORP:
                    break;

                case OpCode.LANDP:
                    break;

                case OpCode.BORP:
                    break;

                case OpCode.BXORP:
                    break;

                case OpCode.BANDP:
                    break;

                case OpCode.SARP:
                    break;

                case OpCode.SALP:
                    break;

                case OpCode.SRP:
                    break;

                case OpCode.CP:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var srcSlot = ins.GetRegisterSlot(1);

                    Expression src;
                    if (ex.ContainsKey(srcSlot))
                    {
                        src = ex[srcSlot];
                    }
                    else
                    {
                        src = new LocalExpression(context.Object, srcSlot);
                    }

                    Expression dst = null;
                    if (ex.ContainsKey(dstSlot))
                    {
                        //dst = ex[dstSlot];
                        ex[dstSlot] = src;
                    }
                    else if (dstSlot < -2)
                    {
                        var l = new LocalExpression(context.Object, dstSlot);
                        //if (!l.IsParameter)
                        //{
                        //    expList.Add(l);
                        //}
                        dst         = l;
                        ex[dstSlot] = l;     //assignment -> statements, local -> expressions

                        BinaryExpression b = new BinaryExpression(dst, src, BinaryOp.Assign)
                        {
                            IsDeclaration = true
                        };
                        //ex[dstSlot] = b;
                        expList.Add(b);
                    }
                    else if (dstSlot != 0)
                    {
                        ex[dstSlot] = src;
                    }
                }
                break;

                //Binary Operation
                case OpCode.ADD:
                case OpCode.SUB:
                case OpCode.MOD:
                case OpCode.DIV:
                case OpCode.IDIV:
                case OpCode.MUL:
                case OpCode.BAND:
                case OpCode.BOR:
                case OpCode.BXOR:
                case OpCode.LAND:
                case OpCode.LOR:
                case OpCode.SAR:
                case OpCode.SAL:
                case OpCode.SR:
                case OpCode.CHKINS:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var srcSlot = ins.GetRegisterSlot(1);
                    var store   = false;   //Set to Expression
                    var declare = false;   //Is declaration

                    Expression dst = null;
                    if (ex.ContainsKey(dstSlot))
                    {
                        dst = ex[dstSlot];
                    }
                    else if (dstSlot < -2)
                    {
                        var l = new LocalExpression(context.Object, dstSlot);
                        //if (!l.IsParameter)
                        //{
                        //    expList.Add(l);
                        //}
                        dst         = l;
                        ex[dstSlot] = l;
                        store       = false;
                        declare     = true;
                    }

                    Expression src;
                    if (ex.ContainsKey(srcSlot))
                    {
                        src = ex[srcSlot];
                    }
                    else
                    {
                        src = new LocalExpression(context.Object, srcSlot);
                    }

                    var op = BinaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.ADD:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUB:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MOD:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIV:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIV:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MUL:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BAND:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BOR:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXOR:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LAND:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LOR:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SAR:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SAL:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SR:
                        op = BinaryOp.BitShiftRight;
                        break;

                    //case OpCode.CP: //moved!
                    //    op = BinaryOp.Assign;
                    //    push = true;
                    //break;
                    case OpCode.CHKINS:
                        op = BinaryOp.InstanceOf;
                        break;
                    }

                    BinaryExpression b = new BinaryExpression(dst, src, op)
                    {
                        IsDeclaration = declare
                    };

                    if (store)
                    {
                        ex[dstSlot] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDPD:
                case OpCode.SUBPD:
                case OpCode.MODPD:
                case OpCode.DIVPD:
                case OpCode.IDIVPD:
                case OpCode.MULPD:
                case OpCode.BANDPD:
                case OpCode.BORPD:
                case OpCode.BXORPD:
                case OpCode.LANDPD:
                case OpCode.LORPD:
                case OpCode.SARPD:
                case OpCode.SALPD:
                case OpCode.SRPD:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.Data.AsString();
                    var op   = BinaryOp.Unknown;

                    var src = ex[ins.GetRegisterSlot(3)];
                    switch (ins.OpCode)
                    {
                    case OpCode.ADDPD:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUBPD:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MODPD:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIVPD:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIVPD:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MULPD:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BANDPD:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BORPD:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXORPD:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LANDPD:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LORPD:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SARPD:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SALPD:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SRPD:
                        op = BinaryOp.BitShiftRight;
                        break;
                    }

                    BinaryExpression b = new BinaryExpression(new IdentifierExpression(name)
                        {
                            Instance = ex[obj]
                        },
                                                              src, op);

                    if (res != 0)
                    {
                        ex[res] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDPI:
                case OpCode.SUBPI:
                case OpCode.MODPI:
                case OpCode.DIVPI:
                case OpCode.IDIVPI:
                case OpCode.MULPI:
                case OpCode.BANDPI:
                case OpCode.BORPI:
                case OpCode.BXORPI:
                case OpCode.LANDPI:
                case OpCode.LORPI:
                case OpCode.SARPI:
                case OpCode.SALPI:
                case OpCode.SRPI:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);
                    var op   = BinaryOp.Unknown;

                    var src = ex[ins.GetRegisterSlot(3)];
                    switch (ins.OpCode)
                    {
                    case OpCode.ADDPI:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUBPI:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MODPI:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIVPI:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIVPI:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MULPI:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BANDPI:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BORPI:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXORPI:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LANDPI:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LORPI:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SARPI:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SALPI:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SRPI:
                        op = BinaryOp.BitShiftRight;
                        break;
                    }

                    BinaryExpression b =
                        new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), src, op);

                    if (res != 0)
                    {
                        ex[res] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDP:
                    break;

                case OpCode.SUBP:
                    break;

                case OpCode.MODP:
                    break;

                case OpCode.DIVP:
                    break;

                case OpCode.IDIVP:
                    break;

                case OpCode.MULP:
                    break;

                case OpCode.EVAL:
                    break;

                case OpCode.EEXP:
                    break;

                case OpCode.ASC:
                    break;

                case OpCode.CHR:
                    break;

                case OpCode.CHKINV:
                    break;

                //Invoke
                case OpCode.CALL:
                {
                    var call = new InvokeExpression(((OperandData)ins.Data).Variant as TjsCodeObject);
                    var dst  = ins.GetRegisterSlot(0);
                    call.Instance = null;
                    var paramCount = ins.GetRegisterSlot(2);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(3 + j);
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.CALLD:
                {
                    var callMethodName = ins.Data.AsString();
                    var call           = new InvokeExpression(callMethodName);
                    var dst            = ins.GetRegisterSlot(0);
                    var callerSlot     = ins.GetRegisterSlot(1);
                    call.Instance = ex[callerSlot];
                    var paramCount = ins.GetRegisterSlot(3);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(4 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    if (dst == 0)     //just execute and discard result
                    {
                        //Handle RegExp()._compile("//g/[^A-Za-z]")
                        if (callMethodName == Const.RegExpCompile)
                        {
                            if (call.Instance is InvokeExpression invoke && invoke.Method == Const.RegExp)
                            {
                                call.InvokeType = InvokeType.RegExpCompile;
                                ex[callerSlot]  = call;
                                break;
                            }
                        }

                        expList.Add(call);
                    }
                }
                break;

                case OpCode.CALLI:
                {
                    //InvokeExpression call = null;
                    //var operand = ((OperandData) ins.Data).Variant;
                    //if (operand is TjsString str)
                    //{
                    //    call = new InvokeExpression(str.StringValue);
                    //}
                    //else
                    //{
                    //    call = new InvokeExpression(operand as TjsCodeObject);
                    //}
                    InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(2)]);
                    var dst        = ins.GetRegisterSlot(0);
                    var callerSlot = ins.GetRegisterSlot(1);
                    call.Instance = ex[callerSlot];
                    var paramCount = ins.GetRegisterSlot(3);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(4 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.NEW:
                {
                    InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(1)])
                    {
                        InvokeType = InvokeType.Ctor
                    };
                    var dst = ins.GetRegisterSlot(0);
                    call.Instance = null;
                    var paramCount = ins.GetRegisterSlot(2);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(3 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.GPD:
                case OpCode.GPDS:
                {
                    var dst      = ins.GetRegisterSlot(0);
                    var slot     = ins.GetRegisterSlot(1);
                    var instance = ex[slot];
                    var name     = ins.Data.AsString();
                    var newId    = new IdentifierExpression(name)
                    {
                        Instance = instance
                    };
                    ex[dst] = newId;
                }
                break;

                case OpCode.GPI:
                case OpCode.GPIS:
                {
                    var dst  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);

                    PropertyAccessExpression p = new PropertyAccessExpression(ex[name], ex[obj]);
                    ex[dst] = p;
                }
                break;

                case OpCode.SPI:
                case OpCode.SPIE:
                case OpCode.SPIS:
                {
                    var obj  = ins.GetRegisterSlot(0);
                    var name = ins.GetRegisterSlot(1);
                    var src  = ins.GetRegisterSlot(2);

                    BinaryExpression b = new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]),
                                                              ex[src], BinaryOp.Assign);
                    expList.Add(b);     //there is no other way to find this expression
                }
                break;

                //Set
                case OpCode.SPD:
                case OpCode.SPDE:
                case OpCode.SPDEH:
                case OpCode.SPDS:
                {
                    var left = new IdentifierExpression(ins.Data.AsString())
                    {
                        Instance = ex[ins.GetRegisterSlot(0)]
                    };
                    var right          = ex[ins.GetRegisterSlot(2)];
                    BinaryExpression b = new BinaryExpression(left, right, BinaryOp.Assign);
                    //check declare
                    if (context.Object.ContextType == TjsContextType.TopLevel)
                    {
                        if (!context.RegisteredMembers.ContainsKey(left.Name))
                        {
                            b.IsDeclaration = true;
                            var stub = new TjsStub();
                            if (right is ConstantExpression con)     //TODO: better type check
                            {
                                stub.Type = con.DataType;
                            }

                            context.RegisteredMembers[left.Name] = stub;
                        }
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.SETP:
                {
                }
                break;

                case OpCode.GETP:
                {
                }
                break;

                //Delete
                case OpCode.DELD:
                    DeleteExpression d = new DeleteExpression(ins.Data.AsString());
                    d.Instance = ex[ins.GetRegisterSlot(1)];
                    expList.Add(d);
                    break;

                case OpCode.DELI:
                    DeleteExpression d2 = new DeleteExpression(ex[ins.GetRegisterSlot(2)]);
                    d2.Instance = ex[ins.GetRegisterSlot(1)];
                    //Check declare
                    if (d2.Instance is IdentifierExpression toDel)
                    {
                        if (context.RegisteredMembers.ContainsKey(toDel.Name))
                        {
                            context.RegisteredMembers.Remove(toDel.Name);
                        }
                    }

                    expList.Add(d2);
                    break;

                case OpCode.SRV:
                {
                    var srv = ins.GetRegisterSlot(0);
                    retExp = srv == 0 ? null : ex[srv];
                }
                break;

                case OpCode.RET:
                {
                    expList.Add(new ReturnExpression(retExp));
                }
                break;

                case OpCode.ENTRY:
                    break;

                case OpCode.EXTRY:
                    break;

                case OpCode.THROW:
                {
                    var th = new ThrowExpression(ex[ins.GetRegisterSlot(0)]);
                    expList.Add(th);
                }
                break;

                case OpCode.CHGTHIS:
                    break;

                case OpCode.GLOBAL:
                {
                    ex[ins.GetRegisterSlot(0)] = Global;
                }
                break;

                case OpCode.ADDCI:
                    break;

                case OpCode.REGMEMBER:
                    break;

                case OpCode.DEBUGGER:
                    break;

                case OpCode.LAST:
                    break;

                case OpCode.PreDec:
                    break;

                case OpCode.PostInc:
                    break;

                case OpCode.PostDec:
                    break;

                case OpCode.Delete:
                    break;

                case OpCode.FuncCall:
                    break;

                case OpCode.IgnorePropGet:
                    break;

                case OpCode.IgnorePropSet:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            expList.RemoveAll(node => node is Expression exp && exp.Parent != null);

            //Save states
            ex[Const.FlagReg] = flag;
            context.BlockFinalStates[block] = ex;

            //Process next
            foreach (var succ in block.To)
            {
                BlockProcess(context, succ, ex); //TODO: deep copy flag?
            }
        }
Exemple #22
0
 public void VisitInvokeExpression(InvokeExpression node) => InferSimpleType(node.GetMethod(_context).ReturnType);
Exemple #23
0
 public override void Visit(InvokeExpression exp)
 {
     exp.AddressEpr.AcceptVisitor(this);
     cb.Write('(');
     cb.Write(")");
 }
        private LinqExpression ResolveMethod(Type hostClass, InvokeExpression call)
        {
            throw new NotImplementedException(call.ToString());
//            var isExtension = hostClass != null;
//            if (isExtension)
//            {
//                var args = new List<RelinqScriptExpression>(call.Args);
//                args.Insert(0, call.Target);
//                call = new InvokeExpression(call.Name, new ConstantExpression("null"), args);
//            }
//
//            hostClass = hostClass ?? Visit(call.Target).Type;
//            var mis = isExtension ?
//                hostClass.GetMethods(BindingFlags.Static | BindingFlags.Public) :
//                // Only instance methods for non-extension invocations
//                hostClass.GetMethods(BindingFlags.Instance | BindingFlags.Public);
//
//            var mrs = mis
//                .Where(mi => mi.Name == call.Name)
//                .Where(mi => !isExtension || mi.IsExtension())
//                .Select(mi => new MethodResolution(mi, _closure, call));
//
//            // First pass matches formal and actual (a.k.a. "real") arguments using available types.
//            // While matching it also tries to infer generic arguments of the method.
//            //
//            // Since typeinfo in JS is quite often incomplete the following arguments will not be used
//            // for generic arguments inference:
//            //  * Function-type parameters (tho matches arg count of an underlying delegate)
//            //  * Object definitions (when used as func arguments they need type info in order to be inferred)
//            //
//            // Second pass iteratively applies  
//
//            var success = mrs.SingleOrDefault(mr => mr.Resolve(ResolutionPass.First) != false);
//            if (success != null)
//            {
//                success.Resolve(ResolutionPass.Second);
//                return success.ResolvedCall;
//            }
//            else
//            {
//                return null;
//            }
        }
Exemple #25
0
 public InvokeStatement(InvokeExpression invokeExp)
 {
     InvokeExp = invokeExp ?? throw new ArgumentNullException(nameof(invokeExp));
 }
Exemple #26
0
        private IExpression ParseSimpleTermExpression()
        {
            Token token = this.lexer.NextToken();

            if (token == null)
            {
                return(null);
            }

            if (token.TokenType == TokenType.Name && token.Value == "function")
            {
                return(ParseFunctionExpression());
            }

            switch (token.TokenType)
            {
            case TokenType.Separator:
                if (token.Value == "(")
                {
                    IExpression expression = this.ParseExpression();
                    this.Parse(TokenType.Separator, ")");
                    return(expression);
                }

                if (token.Value == "{")
                {
                    return(this.ParseObjectExpression());
                }

                break;

            case TokenType.Boolean:
                bool booleanValue = Convert.ToBoolean(token.Value);
                return(new ConstantExpression(booleanValue));

            case TokenType.Integer:
                int intValue = Int32.Parse(token.Value, System.Globalization.CultureInfo.InvariantCulture);
                return(new ConstantExpression(intValue));

            case TokenType.Real:
                double realValue = Double.Parse(token.Value, System.Globalization.CultureInfo.InvariantCulture);
                return(new ConstantExpression(realValue));

            case TokenType.String:
                return(new ConstantExpression(token.Value));

            case TokenType.Object:
                if (token.Value == "null")
                {
                    return(new ConstantExpression(null));
                }

                if (token.Value == "undefined")
                {
                    return(new ConstantExpression(Undefined.Instance));
                }

                break;

            case TokenType.Name:
                IExpression expr = null;

                expr = new VariableExpression(token.Value);

                if (this.TryParse(TokenType.Separator, "("))
                {
                    IList <IExpression> arguments = this.ParseArgumentList();
                    expr = new InvokeExpression(expr, arguments);
                }

                return(expr);
            }

            throw new UnexpectedTokenException(token);
        }
Exemple #27
0
        private IEnumerable <IStatement> ParseMethodExecutions(IEnumerable <string> lines)
        {
            var result = new List <IStatement>();

            int controlsequenceDepth = 0;

            foreach (string line in lines.Select(entry => entry.Trim()))
            {
                if (this.IsLineIgnored(line))
                {
                    continue;
                }

                if (line == "{")
                {
                    continue;
                }

                if (line == "}")
                {
                    if (controlsequenceDepth > 0)
                    {
                        result.Add(new ControlStatementEnd());
                        controlsequenceDepth--;
                    }

                    continue;
                }


                IStatement statement;
                if (this.Class.Name == "FightCommonInformations")
                {
                }

                if (Regex.IsMatch(line, ControlStatement.Pattern))
                {
                    statement = ControlStatement.Parse(line);
                    controlsequenceDepth++;
                }

                else if (Regex.IsMatch(line, AssignationStatement.Pattern))
                {
                    statement = AssignationStatement.Parse(line);
                }

                else if (Regex.IsMatch(line, InvokeExpression.Pattern))
                {
                    statement = InvokeExpression.Parse(line);
                    if (!string.IsNullOrEmpty((statement as InvokeExpression).ReturnVariableAssignation) &&
                        string.IsNullOrEmpty((statement as InvokeExpression).Preffix) &&
                        this.Fields.Count(entry => entry.Name == ((InvokeExpression)statement).ReturnVariableAssignation) > 0)
                    {
                        (statement as InvokeExpression).Preffix = "("
                                                                  + this.Fields.Where(entry =>
                                                                                      entry.Name == ((InvokeExpression)statement).ReturnVariableAssignation)
                                                                  .First()
                                                                  .Type
                                                                  + ")"; // cast
                    }

                    // cast to generic type
                    if (!string.IsNullOrEmpty((statement as InvokeExpression).Target) &&
                        (statement as InvokeExpression).Name == "Add" &&
                        this.Fields.Count(entry => entry.Name == ((InvokeExpression)statement).Target.Split('.').Last()) > 0)
                    {
                        string generictype = this.Fields.Where(entry => entry.Name == ((InvokeExpression)statement).Target.Split('.').Last()).First().Type.Split('<').Last().Split('>').First();

                        (statement as InvokeExpression).Args[0] = "(" + generictype + ")" + (statement as InvokeExpression).Args[0];
                    }
                }

                else
                {
                    statement = new UnknownStatement {
                        Value = line
                    }
                };

                result.Add(statement);
            }

            return(result);
        }
Exemple #28
0
        private Expression BindFunctionInvocation(ExpressionNode node, Token sourceToken, string functionName, ExpressionNode[] argumentNodes)
        {
            // This takes care of explicit conversions
            if (argumentNodes.Length == 1 && Scope.TryLookupType(functionName, out var type))
            {
                return(BindConversion(argumentNodes[0], type, allowExplicit: true));
            }

            var candidates = Scope.LookupFunctions(functionName).ToArray();

            if (candidates.Length == 0)
            {
                diagnostics.ReportUndefinedFunction(sourceToken, functionName);
                return(new InvalidExpression(null));
            }

            var boundArguments = new List <Expression>();

            foreach (var argumentNode in argumentNodes)
            {
                var boundArgument = BindExpression(argumentNode);
                boundArguments.Add(boundArgument);
            }

            var arguments = boundArguments.ToArray();

            // Now let's first look for a definition with the exact same parameters
            foreach (var candidate in candidates)
            {
                var found = MatchStrictOverload(candidate, arguments);
                if (found != null)
                {
                    return(new InvokeExpression(candidate, arguments));
                }
            }

            // No exact parameter match, let's see if we can find functions that would be compatible with implicit conversions
            InvokeExpression invokeExpression = null;
            var findCount = 0;

            foreach (var candidate in candidates)
            {
                var found = MatchCompatibleOverload(node, candidate, arguments, out var convertedArguments);
                if (found != null)
                {
                    invokeExpression = new InvokeExpression(found, convertedArguments);
                    findCount++;
                    if (findCount > 1)
                    {
                        diagnostics.ReportAmbiguousFunction(
                            sourceToken, functionName, arguments.Select(a => a.Type.Name).ToArray());
                        return(new InvalidExpression(invokeExpression));
                    }
                }
            }

            // No compatible signature was found
            if (invokeExpression == null)
            {
                diagnostics.ReportUndefinedFunctionWithArguments(
                    sourceToken, functionName, arguments.Select(a => a.Type.Name).ToArray());
                return(new InvalidExpression(new InvokeExpression(candidates.First(), arguments)));
            }

            // OK, we found one and only one matching overload
            return(invokeExpression);
        }
Exemple #29
0
 internal virtual void VisitInvokeExpr(InvokeExpression invoke)
 {
 }
Exemple #30
0
 get => this.GetRequired(InvokeExpression, Expression.Parse);