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)); }
/// <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()); }
public virtual void Visit(InvokeExpression exp) { exp.AddressEpr.AcceptVisitor(this); if (exp.HasArguments) { foreach (var argument in exp.Arguments) { argument.AcceptVisitor(this); } } }
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); }
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); }
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); }
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)) )); }
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); }
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(')'); }
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); } }
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); } }
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); }
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)); }
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()); } }
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? } }
public void VisitInvokeExpression(InvokeExpression node) => InferSimpleType(node.GetMethod(_context).ReturnType);
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; // } }
public InvokeStatement(InvokeExpression invokeExp) { InvokeExp = invokeExp ?? throw new ArgumentNullException(nameof(invokeExp)); }
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); }
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); }
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); }
internal virtual void VisitInvokeExpr(InvokeExpression invoke) { }
get => this.GetRequired(InvokeExpression, Expression.Parse);