Exemple #1
0
            private ScriptInfo InternalAdd(string scriptString, string scriptKey, JSRuntime runtime)
            {
                Debug.Assert(scriptKey != null, "Invalid scriptKey, should be string");
                ScriptInfo script = null;

                if (!Scripts.TryGetValue(scriptKey, out script))
                {
                    script = Scripts.GetOrAdd(scriptKey, key =>
                    {
                        Debug.WriteLine("Script precompilation cache {0} [miss]", key);
                        JSRuntime.Instance = runtime;
                        var scriptInfo     = new ScriptInfo(key, scriptString);
                        scriptInfo.LexTask = System.Threading.Tasks.Task.Factory.StartNew(state =>
                        {
                            var taskState = state as JSTaskState <ScriptInfo>;
                            var info      = taskState.GetState();
                            var timer     = JSRuntime.StartTimer(true, "JS/PreLoad/" + key);
                            info.Metadata = taskState.RuntimeInstance.LoadScriptStringMetadata(info.Text);
                            if (Instance.Configuration.EnableParallelJit)
                            {
                                info.Metadata.JitSpeculatively(ref mdr.DFunctionSignature.EmptySignature);
                            }
                            else if (Instance.Configuration.EnableParallelAnalyze)
                            {
                                info.Metadata.Analyze(); //Will launch the rest itself.
                            }
                            JSRuntime.StopTimer(timer);
                        }, new JSTaskState <ScriptInfo>(scriptInfo));
                        return(scriptInfo);
                    });
                }
                else
                {
                    Debug.WriteLine("Script precompilation cache {0} [hit]", scriptKey);
                }
                return(script);
            }
        /// <summary>
        /// Prepare() is called once before the first execution of function.
        /// </summary>
        void Prepare()
        {
            if (CurrentStatus < Status.Preparing)
            {
                Analyze();

                var configuration = JSRuntime.Instance.Configuration;

                CurrentStatus = Status.Preparing;

                ParametersMask.Value = mdr.DFunctionSignature.GetMask(ParametersCount);

                //TODO: heuristic to disable TypeInference, we can also see if the func does not have any argument AND the "arguments" variable is not referenced in the functiob body
                EnableTypeInference =
                    configuration.EnableTypeInference &&
                    configuration.EnableJIT &&
                    (ParametersCount <= mdr.DFunctionSignature.TypesPerElement) &&
                    (Scope.HasLoop || Scope.Symbols.Count > 0)
                ;

                //if (ParametersCount <= mdr.DFunctionSignature.TypesPerElement)
                if (EnableTypeInference)
                {
                    SignatureMask.Value = ParametersMask.Value;
                }
                else
                {
                    SignatureMask.Value = mdr.DFunctionSignature.EmptySignature.Value;
                }


                //TODO: make this a configuration parameter.
                EnableProfiling = configuration.EnableProfiling && !IsBlackListed;

                FunctionDeclarationHoister.Execute(this);

                if (configuration.EnableMethodCallResolution)
                {
                    MethodResolver.Execute(this);
                }

                EnableInlineCache = configuration.EnableInlineCache;

                var timer =
                    configuration.ProfileFunctionTime
          ? JSRuntime.StartTimer(configuration.ProfileJitTime, "JS/SymInit/" + Declaration)
          : JSRuntime.StartTimer(configuration.ProfileJitTime, "JS/SymInit");
                try
                {
                    var symbols = Scope.Symbols;

                    for (var i = symbols.Count - 1; i >= 0; --i)
                    {
                        var symbol = symbols[i];

                        if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal ||
                            symbol.SymbolType == JSSymbol.SymbolTypes.ParentLocal ||
                            symbol.SymbolType == JSSymbol.SymbolTypes.Global ||
                            symbol.SymbolType == JSSymbol.SymbolTypes.Unknown
                            )
                        {
                            symbol.AssignFieldId();
                        }
                        Debug.Assert(
                            !symbol.IsParameter
                            ||
                            (symbol.Index == i &&
                             (
                                 (symbol.ParameterIndex == i && (Scope.IsFunctionDeclaration || FunctionIR.Name == null)) ||
                                 (symbol.ParameterIndex == (i - 1) && !Scope.IsFunctionDeclaration && FunctionIR.Name != null)
                             )
                            )
                            , "Invalid situation!, symbol {0} should be paramter with parameter index {1} instead of {2}", symbol.Name, i, symbol.ParameterIndex);
                    }
                }
                finally
                {
                    JSRuntime.StopTimer(timer);
                }

                CurrentStatus = Status.Prepared;
            }
        }