예제 #1
0
 public override void Visit(CallExpression node)
 {
   if (node.InlinedIR != null)
     VisitNode(node.InlinedIR);
   else
     Visit((Invocation)node);
 }
예제 #2
0
      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();
      }
예제 #3
0
 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;
 }
예제 #4
0
 public override void Visit(CallExpression node) { base.Visit(node); node.ValueType = GetType(node); }
예제 #5
0
      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();
      }
예제 #6
0
 public override void Visit(CallExpression node) { Visit((Invocation)node); }
예제 #7
0
      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();
      }
예제 #8
0
      //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);
      }
예제 #9
0
 public override void Visit(CallExpression node)
 {
     Visit((Invocation)node);
 }
예제 #10
0
    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;
    }
예제 #11
0
 public abstract void Visit(CallExpression node);
예제 #12
0
      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();
      }
예제 #13
0
 public override void Visit(CallExpression node) { AssignToImplicitReturn(node); }