示例#1
0
      protected virtual LocalBuilder CreateCallFrame(Invocation node)
      {
        var callFrame = _localVars.PushTemporary(Types.CallFrame.TypeOf);

        _ilGen.Ldloca(callFrame);
        _ilGen.Initobj(Types.CallFrame.TypeOf);

        _ilGen.Ldloca(callFrame);
        VisitNode(node.Function);
        Debug.Assert(_result.ValueType == mdr.ValueTypes.Function, "Invalid situation, {0} is not a function value type", node.Function);
        _ilGen.Stfld(Types.CallFrame.Function);

        _ilGen.Ldloca(callFrame);
        _ilGen.Ldflda(Types.CallFrame.Signature);
        _ilGen.Ldc_U8(0);
        _ilGen.Stfld(Types.DFunctionSignature.Value);


        _ilGen.Ldloca(callFrame);
        _ilGen.Ldc_I4(node.Arguments.Count);
        _ilGen.Stfld(Types.CallFrame.PassedArgsCount);

        var argsArraySize = node.Arguments.Count - mdr.CallFrame.InlineArgsCount;
        if (argsArraySize > 0)
        {
          _ilGen.Ldloca(callFrame);
          _ilGen.Ldc_I4(argsArraySize);
          _ilGen.NewArr(Types.DValue.TypeOf);
          _ilGen.Stfld(Types.CallFrame.Arguments);
        }

        if (JSRuntime.Instance.Configuration.ProfileStats)
          GenCounterIncrement("Args_" + node.Arguments.Count.ToString(), null, 1);

        return callFrame;
      }
示例#2
0
      mdr.DFunctionCode LoadArguments(Invocation node, LocalBuilder callFrame)
      {
        var knownStaticSignature = mdr.DFunctionSignature.EmptySignature;
        var staticallyTypedArgsCount = 0;


        for (var argIndex = 0; argIndex < node.Arguments.Count; ++argIndex)
        {
          var passedArg = node.Arguments[argIndex];

          _ilGen.Ldloca(callFrame);
          Ldarg_Parameter(argIndex, true);
          VisitNode(passedArg);
          var argType = _result.ValueType;
          _ilGen.Call(Types.DValue.Set.Get(argType));

          if (argType < mdr.ValueTypes.DValue)
          {
            knownStaticSignature.InitArgType(argIndex, argType);
            ++staticallyTypedArgsCount;
          }
          else
          {
            _ilGen.Ldloca(callFrame);
            _ilGen.Ldflda(Types.CallFrame.Signature);
            _ilGen.Ldc_I4(argIndex);
            _ilGen.Ldloca(callFrame);
            Ldarg_Parameter(argIndex, true);
            _ilGen.Call(Types.DValue.GetValueType);
            _ilGen.Call(Types.DFunctionSignature.InitArgType);
          }
        }

        if (staticallyTypedArgsCount > 0)
        {
          //Merge static signature with dynamically calculated one.
          _ilGen.Ldloca(callFrame);
          _ilGen.Ldflda(Types.CallFrame.Signature);
#if DEBUG
          //This is to prevent error in our source code generators
          _ilGen.Ldloca(callFrame);
          _ilGen.Ldflda(Types.CallFrame.Signature);
#else
          _ilGen.Dup();
#endif
          _ilGen.Ldfld(Types.DFunctionSignature.Value);
          _ilGen.Ldc_U8(knownStaticSignature.Value);
          _ilGen.Or();
          _ilGen.Stfld(Types.DFunctionSignature.Value);
        }

        ///If parallel jit is enabled, we try to launch jitting for possible callee functions
        //if (JSRuntime.Instance.Configuration.EnableParallelJit)
        //{
        //  string lookupKey = null;
        //  var id = function as Identifier;
        //  if (id != null)
        //    lookupKey = id.Text;
        //  else
        //  {
        //    var indexer = function as Indexer;
        //    if (indexer != null && indexer.FieldId != mdr.Runtime.InvalidFieldId)
        //      lookupKey = mdr.Runtime.Instance.GetFieldName(indexer.FieldId);
        //  }
        //  if (lookupKey != null)
        //  {
        //    var funcs = JSRuntime.Instance.Speculator.Get(lookupKey);
        //    if (funcs != null)
        //      foreach (var f in funcs)
        //      {
        //        bool dummy;
        //        f.Jit(ref knownStaticSignature, out dummy);
        //      }
        //  }
        //  else
        //  {
        //    var funcExp = function as FunctionExpression;
        //    if (funcExp != null)
        //    {
        //      bool dummy;
        //      funcExp.Metadata.Jit(ref knownStaticSignature, out dummy);
        //    }
        //  }
        //}

        var targetFuncMetadata = node.TargetFunctionMetadata;
        bool canEmitDirectCalls =
          targetFuncMetadata != null
          && JSRuntime.Instance.Configuration.EnableDirectCalls
          && staticallyTypedArgsCount == node.Arguments.Count;
        if (
            canEmitDirectCalls
            && targetFuncMetadata.CurrentStatus != JSFunctionMetadata.Status.Jitting //FIXME: for now we disable recursive direct calls because CreateDelegate may throw if current method calls unfinised methods
            )
        {
          StopJitTimer();
          //knownStaticSignature.Value |= unknownStaticSignature.Value; //We now can messup with this signature.
          Debug.WriteLine("Looking for {0} with sig=0x{1:X}", targetFuncMetadata.Declaration, knownStaticSignature.Value);
          var targetCode = targetFuncMetadata.JitSpeculatively(ref knownStaticSignature);
          StartJitTimer();

          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.

            if (targetCode.Method == null)
            {
              //TODO: add targetcode to list to wait for it!
            }

            //var targetCode = targetFuncMetadata.UniqueInstance;
            //if (targetCode == null)
            //{
            //    targetCode = targetFuncMetadata.Cache.Get(staticSignature.Value);
            //    if (targetCode == null)
            //        targetCode = expression.TargetFunctionMetadata.Jit(ref staticSignature);
            //}
          }
          return targetCode;
        }
        return null;
      }
示例#3
0
 protected override void Visit(Invocation node) { Visit((Expression)node); }
示例#4
0
 protected override void Visit(Invocation node)
 {
   VisitNode(node.Function);
   VisitNodes(node.Arguments);
   Visit((Expression)node);
 }
示例#5
0
      void DetectTargetFuncMetadata(JSFunctionMetadata functionMetadata, Invocation expression, Expression function)
      {
        // functions declared in the global scope can be overwritten by other functions or 
        // other scripts in the page, so do not resolve!

        var parenExp = function as ParenExpression;
        if (parenExp != null)
        {
          DetectTargetFuncMetadata(functionMetadata, expression, parenExp.Expression);
          return;
        }

        var toFunction = function as ToFunction;
        if (toFunction != null)
        {
          DetectTargetFuncMetadata(functionMetadata, expression, toFunction.Expression);
          return;
        }

        var funcExp = function as FunctionExpression;
        if (funcExp != null)
        {
          Debug.WriteLine(new JSSourceLocation(functionMetadata, expression), "  function expression detected.");
          expression.TargetFunctionMetadata = funcExp.Metadata;
          return;
        }
        else
        {
          var id = function as Identifier;
          if (id != null)
          {
            var symbol = id.Symbol;// _currFuncMetadata.GetSymbol(id.Text);
            Debug.WriteLine(new JSSourceLocation(functionMetadata, id), "Method call to {0}:", symbol.Name);
            Debug.Assert(symbol != null, new JSSourceLocation(functionMetadata, id), "Symbol cannot be null here!");
            
            if (symbol.ResolvedSymbol != null)
              symbol = symbol.ResolvedSymbol;
            var jsfunc = symbol.ContainerScope.ContainerFunction;
            //JSFunctionMetadata jsfunc = functionMetadata;
            //for (int i = 0; i < symbol.AncestorDistance; i++)
            //  jsfunc = jsfunc.ParentFunction;

            //if (!jsfunc.Scope.IsProgram) //do not resolve global function declaration targets
            if (!symbol.ContainerScope.IsProgram)
            {
              //symbol = jsfunc.Scope.GetSymbol(id.Symbol.Name);
              if (symbol.SubFunctionIndex != mdr.Runtime.InvalidIndex && symbol.NonLocalWritersCount == 0)
              {
                expression.TargetFunctionMetadata = jsfunc.SubFunctions[symbol.SubFunctionIndex];
                // we have found the corresponding JSFunctionImp instance
                Debug.WriteLine(new JSSourceLocation(jsfunc, expression), string.Format("function declaration found. JSFunctionImp name: {0}", jsfunc.SubFunctions[symbol.SubFunctionIndex].FullName));
              }
              else if (symbol.Writers.Count == 1)
              {
                // if a symbol is assigned once and the assigned expression is a function, we can find
                // the corresponding JSFunctionImp statically when the variable is called. For example: var x = function() {}; x();
                var wfunc = symbol.Writers[0].Value as FunctionExpression;
                if (wfunc != null)
                {
                  Debug.Write(new JSSourceLocation(functionMetadata, wfunc), "  function expression detected.");
                  expression.TargetFunctionMetadata = wfunc.Metadata;
                }
              }
            }
            else
              Debug.WriteLine(new JSSourceLocation(jsfunc, expression), "function {0} was not resolved because it was declared globally", jsfunc.Declaration);
          }
        }
        Debug.WriteLine("");
        return;
      }
      protected override LocalBuilder CreateCallFrame(Invocation node)
      {
        var callFrame = base.CreateCallFrame(node);

        int profIndex = _currFuncMetadata.GetProfileIndex(node);
        _ilGen.Ldloc(_profiler);
        _ilGen.Ldc_I4(profIndex);
        _ilGen.Ldloca(callFrame);
        _ilGen.Ldfld(Types.CallFrame.Function);
        _ilGen.Call(Types.Operations.Internals.UpdateCallProfile);

        return callFrame;
      }
示例#7
0
 protected virtual void Visit(Invocation node)
 {
 }
示例#8
0
 internal void PopLocation(Invocation node, mdr.DFunction callTarget)
 {
   if (_currProfiler != null)
   {
     _currProfiler.GetOrAddNodeProfile(node).UpdateNodeProfile(callTarget);
     //NodeProfile nProfile = _currProfiler.GetNodeProfile(functionExpr);
     //if (nProfile != null)
     //{
     //  (nProfile as CallNodeProfile).UpdateNodeProfile(callTarget);
     //}
     //else
     //{
     //  _currProfiler.CreateNewProfile(functionExpr, callTarget);
     //}
   }
 }
示例#9
0
 public int GetProfileIndex(Invocation node) { return (node.ProfileIndex == -1) ? (node.ProfileIndex = InvocationNodeCount++) : node.ProfileIndex; }