public override void Visit(CallExpression node) { if (node.InlinedIR != null) VisitNode(node.InlinedIR); else Visit((Invocation)node); }
public override void Visit(CallExpression node) { if (node.InlinedIR != null) { VisitNode(node.InlinedIR); return; } PushLocation(node); var stackState = _localVars.GetTemporaryStackState(); var callFrame = CreateCallFrame(node); if (node.ThisArg != null) { _ilGen.Ldloca(callFrame); VisitNode(node.ThisArg); AsDObject(); _ilGen.Stfld(Types.CallFrame.This); } else if (node.IsDirectEvalCall) { //This could be direct eval call _ilGen.Ldloca(callFrame); Ldarg_CallFrame(); _ilGen.Ldfld(Types.CallFrame.Function); _ilGen.Stfld(Types.CallFrame.CallerFunction); _ilGen.Ldloca(callFrame); _ilGen.Ldloc(_context); _ilGen.Stfld(Types.CallFrame.CallerContext); _ilGen.Ldloca(callFrame); Ldarg_CallFrame(); _ilGen.Ldfld(Types.CallFrame.This); _ilGen.Stfld(Types.CallFrame.This); } else //if (!node.IsDirectEvalCall) { //TODO: can move this to the callee prolog and only assig global obj in case .This is null; of course that requires we guarantee .This is always reset to null _ilGen.Ldloca(callFrame); _ilGen.LoadRuntimeInstance(); _ilGen.Ldfld(Types.Runtime.GlobalContext); _ilGen.Stfld(Types.CallFrame.This); } var targetCode = LoadArguments(node, callFrame); GenExecTimerStop(true); if (targetCode != null) { //We have everythihng ready on the stack and all params are statically typed //So we can directly call the target function //TODO: we can even use this situation for return type calculation. _ilGen.Ldloca(callFrame); _ilGen.Call(targetCode.MethodHandle); } else { _ilGen.Ldloca(callFrame); _ilGen.Ldfld(Types.CallFrame.Function); _ilGen.Ldloca(callFrame); _ilGen.Call(Types.DFunction.Call); } GenExecTimerStart(true); _localVars.PopTemporariesAfter(stackState); //We need to immediately copy the return value on caller's stack before it gets destroyed var result = _localVars.PushTemporary(Types.DValue.TypeOf); _ilGen.Ldloca(callFrame); _ilGen.Ldflda(Types.CallFrame.Return); _ilGen.Ldobj(Types.DValue.TypeOf); _ilGen.Stloc(result); _ilGen.Ldloca(result); _result.ValueType = mdr.ValueTypes.DValueRef; PopLocation(); }
internal static mdr.ValueTypes GetType(CallExpression expression) { if (expression.InlinedIR != null) return GetType(expression.InlinedIR); else if (expression.TargetFunctionMetadata != null) { //launch a new TI for the target function return mdr.ValueTypes.DValueRef; } else return mdr.ValueTypes.DValueRef; }
public override void Visit(CallExpression node) { base.Visit(node); node.ValueType = GetType(node); }
public override void Visit(CallExpression node) { PushLocation(node); VisitNode(node.Function); VisitNode(node.ThisArg); VisitNodes(node.Arguments); var hasThis = node.ThisArg != null; _stackModel.Pop(1 + (hasThis ? 1 : 0) + node.Arguments.Count); BeginICMethod(node); _ilGen.Ldarg_CallFrame(); _ilGen.Ldc_I4(node.Arguments.Count); _ilGen.Ldc_I4(_stackModel.StackPointer); _ilGen.Ldc_I4(hasThis); _ilGen.Ldc_I4(node.IsDirectEvalCall); _ilGen.Call(Types.Operations.ICMethods.Call); EndICMethod(); _result.ValueType = mdr.ValueTypes.DValueRef; _stackModel.Push(1); PopLocation(); }
public override void Visit(CallExpression node) { Visit((Invocation)node); }
void InlineInvocation(CallExpression invocation, JSFunctionMetadata targetFuncMetadata) { _targetFuncMetadata = targetFuncMetadata; _call = invocation; Debug.WriteLine("Trying to inline function {0}", _targetFuncMetadata.Declaration); _targetFuncMetadata.Analyze(); //Just to make sure it is analyzed if (JSRuntime.Instance.Configuration.ProfileStats) JSRuntime.Instance.Counters.GetCounter("Attempted Inline").Count++; if (!CanInline(_targetFuncMetadata)) return; if (JSRuntime.Instance.Configuration.ProfileStats) JSRuntime.Instance.Counters.GetCounter("Succeeded Inline").Count++; _functionsBeingInlined.AddLast(_targetFuncMetadata); _round++; throw new NotImplementedException(); //TODO: we need to update this algorithm based on the recent changes to the scope _newScope = new Scope(_currentTargetScope); _returnValueSymbol = _newScope.AddSymbol(RenameSymbol("retVal")); _returnValueSymbol.SymbolType = JSSymbol.SymbolTypes.HiddenLocal; _call.InlinedIR = new InlinedInvocation( _targetFuncMetadata , _newScope , BuildInlinedBody() , new ReadIdentifierExpression(_returnValueSymbol) ); _call.InlinedIR.AddUser(_call); Debug.WriteLine("Inlined function {0}", _targetFuncMetadata.Declaration); _functionsBeingInlined.RemoveLast(); }
//TODO: if we want to keep inlining "new" operations, we should uncomment the following as well public override void Visit(CallExpression node) { base.Visit(node); _newScope.Invocations.Add((CallExpression)result); }
public CallExpression MakeCallExpression(Scope scope, IExpression function, IExpressionList arguments) { scope.HasCall = true; ///We have to detect the followings immediately now, before future phases modify the IR var func = MakeToFunction((Expression)function); //This will ensure we have uniform type going forward Expression thisArg = null; bool isDirectEvalCall = false; var funcExp = GetEquivalent(func.Expression); var indexer = funcExp as ReadIndexerExpression; if (indexer != null) { thisArg = indexer.Container; } else { var id = funcExp as ReadIdentifierExpression; Debug.WriteLineIf(id == null, "Runtime error or coding error?"); isDirectEvalCall = (id != null && id.Symbol != null && id.Symbol.Name == "eval"); if (isDirectEvalCall) scope.HasEval = isDirectEvalCall; //We have to be carefull not to over write the old value! } var n = new CallExpression(func, thisArg, arguments, isDirectEvalCall); scope.Invocations.Add(n); return n; }
public abstract void Visit(CallExpression node);
public override void Visit(CallExpression node) { PushLocation(node); VisitNode(node.Function); VisitNode(node.ThisArg); VisitNodes(node.Arguments); GenExecTimerStop(true); Ldarg_CallFrame(); _ilGen.Ldloc(_context); _ilGen.Ldc_I4(node.Arguments.Count); var hasThis = node.ThisArg != null; _ilGen.Ldc_I4(hasThis); _ilGen.Ldc_I4(node.IsDirectEvalCall); Call(Types.Operations.Stack.Call, (hasThis ? 1 : 0) + 1 + node.Arguments.Count, 1); GenExecTimerStart(true); PopLocation(); }
public override void Visit(CallExpression node) { AssignToImplicitReturn(node); }