Exemplo n.º 1
0
        /// <summary>
        /// Executes the given source code.  Execution is bound to the global scope.
        /// </summary>
        /// <param name="source"> The javascript source code to execute. </param>
        /// <returns> The result of executing the source code. </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="code"/> is a <c>null</c> reference. </exception>
        public object Evaluate(ScriptSource source)
        {
            var methodGen = new Jurassic.Compiler.EvalMethodGenerator(
                this,                               // The script engine
                this.CreateGlobalScope(),           // The variable scope.
                source,                             // The source code.
                CreateOptions(),                    // The compiler options.
                this.Global);                       // The value of the "this" keyword.

            // Parse
            if (this.ParsingStarted != null)
            {
                this.ParsingStarted(this, EventArgs.Empty);
            }
            methodGen.Parse();

            // Optimize
            if (this.OptimizationStarted != null)
            {
                this.OptimizationStarted(this, EventArgs.Empty);
            }
            methodGen.Optimize();

            // Generate code
            if (this.CodeGenerationStarted != null)
            {
                this.CodeGenerationStarted(this, EventArgs.Empty);
            }
            methodGen.GenerateCode();
            VerifyGeneratedCode();

            // Execute
            if (this.ExecutionStarted != null)
            {
                this.ExecutionStarted(this, EventArgs.Empty);
            }
            var result = methodGen.Execute();

            // Normalize the result (convert null to Undefined, double to int, etc).
            return(TypeUtilities.NormalizeValue(result));
        }
Exemplo n.º 2
0
        //     EVAL SUPPORT
        //_________________________________________________________________________________________

        //private class EvalCacheKey
        //{
        //    public string Code;
        //    public Compiler.Scope Scope;
        //    public bool StrictMode;

        //    public override int GetHashCode()
        //    {
        //        int bitValue = 1;
        //        int hashCode = this.Code.GetHashCode();
        //        var scope = this.Scope;
        //        do
        //        {
        //            if (scope is Compiler.DeclarativeScope)
        //                hashCode ^= bitValue;
        //            scope = scope.ParentScope;
        //            bitValue *= 2;
        //        } while (scope != null);
        //        if (this.StrictMode == true)
        //            hashCode ^= bitValue;
        //        return hashCode;
        //    }

        //    public override bool Equals(object obj)
        //    {
        //        if ((obj is EvalCacheKey) == false)
        //            return false;
        //        var other = (EvalCacheKey) obj;
        //        if (this.Code != other.Code ||
        //            this.StrictMode != other.StrictMode)
        //            return false;
        //        var scope1 = this.Scope;
        //        var scope2 = other.Scope;
        //        do
        //        {
        //            if (scope1.GetType() != scope2.GetType())
        //                return false;
        //            scope1 = scope1.ParentScope;
        //            scope2 = scope2.ParentScope;
        //            if (scope1 == null && scope2 != null)
        //                return false;
        //            if (scope1 != null && scope2 == null)
        //                return false;
        //        } while (scope1 != null);
        //        return true;
        //    }
        //}

        //private Dictionary<EvalCacheKey, WeakReference> evalCache =
        //    new Dictionary<EvalCacheKey, WeakReference>();

        /// <summary>
        /// Evaluates the given javascript source code and returns the result.
        /// </summary>
        /// <param name="code"> The source code to evaluate. </param>
        /// <param name="scope"> The containing scope. </param>
        /// <param name="thisObject"> The value of the "this" keyword in the containing scope. </param>
        /// <param name="strictMode"> Indicates whether the eval statement is being called from
        /// strict mode code. </param>
        /// <returns> The value of the last statement that was executed, or <c>undefined</c> if
        /// there were no executed statements. </returns>
        internal object Eval(string code, Compiler.Scope scope, object thisObject, bool strictMode)
        {
            // Check if the cache contains the eval already.
            //var key = new EvalCacheKey() { Code = code, Scope = scope, StrictMode = strictMode };
            //WeakReference cachedEvalGenRef;
            //if (evalCache.TryGetValue(key, out cachedEvalGenRef) == true)
            //{
            //    var cachedEvalGen = (Compiler.EvalMethodGenerator)cachedEvalGenRef.Target;
            //    if (cachedEvalGen != null)
            //    {
            //        // Replace the "this object" before running.
            //        cachedEvalGen.ThisObject = thisObject;

            //        // Execute the cached code.
            //        return ((Compiler.EvalMethodGenerator)cachedEvalGen).Execute();
            //    }
            //}

            // Parse the eval string into an AST.
            var options = new Compiler.CompilerOptions()
            {
                ForceStrictMode = strictMode
            };
            var evalGen = new Jurassic.Compiler.EvalMethodGenerator(
                this,                                                   // The script engine.
                scope,                                                  // The scope to run the code in.
                new StringScriptSource(code),                           // The source code to execute.
                options,                                                // Options.
                thisObject);                                            // The value of the "this" keyword.

            // Make sure the eval cache doesn't get too big.  TODO: add some sort of LRU strategy?
            //if (evalCache.Count > 100)
            //    evalCache.Clear();

            //// Add the eval method generator to the cache.
            //evalCache[key] = new WeakReference(evalGen);

            // Compile and run the eval code.
            return(evalGen.Execute());
        }