ToObject() public static method

public static ToObject ( Engine engine, Jint.Native.JsValue value ) : Jint.Native.Object.ObjectInstance
engine Engine
value Jint.Native.JsValue
return Jint.Native.Object.ObjectInstance
Esempio n. 1
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.10
        /// </summary>
        /// <param name="withStatement"></param>
        /// <returns></returns>
        public void ExecuteWithStatement(RuntimeState state)
        {
            WithStatement             withStatement = (WithStatement)state.arg;
            ExecuteWithStatementLocal local         = null;

            if (state.stage == 0)
            {
                if (state.calleeReturned)
                {
                    state.calleeReturned = false;
                    state.local          = local = new ExecuteWithStatementLocal();
                    var jsValue = _engine.GetValue(state.calleeReturnValue, true);
                    var obj     = TypeConverter.ToObject(_engine, jsValue);
                    local.oldEnv = _engine.ExecutionContext.LexicalEnvironment;
                    var newEnv = LexicalEnvironment.NewObjectEnvironment(_engine, obj, local.oldEnv, true);
                    _engine.UpdateLexicalEnvironment(newEnv);
                    state.stage = 1;
                }
                else
                {
                    Call(_engine.EvaluateExpression, withStatement.Object);
                    return;
                }
            }

            // Stage 1

            if (local == null)
            {
                local = (ExecuteWithStatementLocal)state.local;
            }

            if (state.calleeReturned)
            {
                _engine.UpdateLexicalEnvironment(local.oldEnv);
                Return(state.calleeReturnValue);
                return;
            }
        }
Esempio n. 2
0
        public JsValue EvaluateUnaryExpression(UnaryExpression unaryExpression)
        {
            var       value = _engine.EvaluateExpression(unaryExpression.Argument);
            Reference r;

            switch (unaryExpression.Operator)
            {
            case UnaryOperator.Plus:
                return(TypeConverter.ToNumber(_engine.GetValue(value)));

            case UnaryOperator.Minus:
                var n = TypeConverter.ToNumber(_engine.GetValue(value));
                return(double.IsNaN(n) ? double.NaN : n *-1);

            case UnaryOperator.BitwiseNot:
                return(~TypeConverter.ToInt32(_engine.GetValue(value)));

            case UnaryOperator.LogicalNot:
                return(!TypeConverter.ToBoolean(_engine.GetValue(value)));

            case UnaryOperator.Delete:
                r = value as Reference;
                if (r == null)
                {
                    return(true);
                }
                if (r.IsUnresolvableReference())
                {
                    if (r.IsStrict())
                    {
                        throw new JavaScriptException(_engine.SyntaxError);
                    }

                    return(true);
                }
                if (r.IsPropertyReference())
                {
                    var o = TypeConverter.ToObject(_engine, r.GetBase());
                    return(o.Delete(r.GetReferencedName(), r.IsStrict()));
                }
                if (r.IsStrict())
                {
                    throw new JavaScriptException(_engine.SyntaxError);
                }
                var bindings = r.GetBase().TryCast <EnvironmentRecord>();
                return(bindings.DeleteBinding(r.GetReferencedName()));

            case UnaryOperator.Void:
                _engine.GetValue(value);
                return(Undefined.Instance);

            case UnaryOperator.TypeOf:
                r = value as Reference;
                if (r != null)
                {
                    if (r.IsUnresolvableReference())
                    {
                        return("undefined");
                    }
                }
                var v = _engine.GetValue(value);
                if (v == Undefined.Instance)
                {
                    return("undefined");
                }
                if (v == Null.Instance)
                {
                    return("object");
                }
                switch (v.Type)
                {
                case Types.Boolean: return("boolean");

                case Types.Number: return("number");

                case Types.String: return("string");
                }
                if (v.TryCast <ICallable>() != null)
                {
                    return("function");
                }
                return("object");

            default:
                throw new ArgumentException();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
        /// </summary>
        /// <param name="forInStatement"></param>
        /// <returns></returns>
        public Completion ExecuteForInStatement(ForInStatement forInStatement)
        {
            Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration
                                        ? forInStatement.Left.As <VariableDeclaration>().Declarations.First().Id
                                        : forInStatement.Left.As <Identifier>();

            var varRef     = _engine.EvaluateExpression(identifier) as Reference;
            var exprRef    = _engine.EvaluateExpression(forInStatement.Right);
            var experValue = _engine.GetValue(exprRef);

            if (experValue == Undefined.Instance || experValue == Null.Instance)
            {
                return(new Completion(Completion.Normal, null, null));
            }


            var     obj = TypeConverter.ToObject(_engine, experValue);
            JsValue v   = Null.Instance;

            // keys are constructed using the prototype chain
            var cursor        = obj;
            var processedKeys = new HashSet <string>();

            while (cursor != null)
            {
                var keys = cursor.GetOwnProperties().Select(x => x.Key).ToArray();
                foreach (var p in keys)
                {
                    if (processedKeys.Contains(p))
                    {
                        continue;
                    }

                    processedKeys.Add(p);

                    // collection might be modified by inner statement
                    if (!cursor.HasOwnProperty(p))
                    {
                        continue;
                    }

                    var value = cursor.GetOwnProperty(p);
                    if (!value.Enumerable.HasValue || !value.Enumerable.Value)
                    {
                        continue;
                    }

                    _engine.PutValue(varRef, p);

                    var stmt = ExecuteStatement(forInStatement.Body);
                    if (stmt.Value.HasValue)
                    {
                        v = stmt.Value.Value;
                    }
                    if (stmt.Type == Completion.Break)
                    {
                        return(new Completion(Completion.Normal, v, null));
                    }
                    if (stmt.Type != Completion.Continue)
                    {
                        if (stmt.Type != Completion.Normal)
                        {
                            return(stmt);
                        }
                    }
                }

                cursor = cursor.Prototype;
            }

            return(new Completion(Completion.Normal, v, null));
        }
Esempio n. 4
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
        /// </summary>
        /// <param name="forInStatement"></param>
        /// <returns></returns>
        public void ExecuteForInStatement(RuntimeState state)
        {
            ForInStatement             forInStatement = (ForInStatement)state.arg;
            ExecuteForInStatementLocal local          = null;

            if (state.stage == 0)
            {
                if (state.calleeReturned)
                {
                    state.calleeReturned = false;
                    local        = (ExecuteForInStatementLocal)state.local;
                    local.varRef = state.calleeReturnValue as Reference;
                    state.stage  = 1;
                }
                else
                {
                    state.local      = local = new ExecuteForInStatementLocal();
                    local.stage      = 0;
                    local.identifier = forInStatement.Left.Type == Nodes.VariableDeclaration
                        ? (Identifier)((VariableDeclaration)forInStatement.Left).Declarations[0].Id
                        : (Identifier)forInStatement.Left;

                    Call(_engine.EvaluateExpression, local.identifier);
                    return;
                }
            }

            if (local == null)
            {
                local = (ExecuteForInStatementLocal)state.local;
            }

            if (state.stage == 1)
            {
                if (state.calleeReturned)
                {
                    state.calleeReturned = false;
                    local.experValue     = _engine.GetValue(state.calleeReturnValue, true);
                    if (local.experValue.IsUndefined() || local.experValue.IsNull())
                    {
                        Return(new Completion(CompletionType.Normal, null, null));
                        return;
                    }

                    local.obj = TypeConverter.ToObject(_engine, local.experValue);
                    JsValue v = Null.Instance;

                    // keys are constructed using the prototype chain
                    local.cursor        = local.obj;
                    local.processedKeys = new HashSet <string>();
                    state.stage         = 2;
                }
                else
                {
                    Call(_engine.EvaluateExpression, forInStatement.Right);
                    return;
                }
            }

            // Stage 2

            if (state.calleeReturned)
            {
                Completion stmt = (Completion)state.calleeReturnValue;

                if (!ReferenceEquals(stmt.Value, null))
                {
                    local.v = stmt.Value;
                }
                if (stmt.Type == CompletionType.Break)
                {
                    Return(new Completion(CompletionType.Normal, local.v, null));
                    return;
                }
                if (stmt.Type != CompletionType.Continue)
                {
                    if (stmt.Type != CompletionType.Normal)
                    {
                        Return(stmt);
                        return;
                    }
                }
            }

            if (local.stage == 0)
            {
                if (!ReferenceEquals(local.cursor, null))
                {
                    Return(new Completion(CompletionType.Normal, local.v, null));
                    return;
                }

                local.stage = 1;
                return;
            }
            if (local.stage == 1) // While loop
            {
                local.keys = _engine.Object.GetOwnPropertyNames(Undefined.Instance, Arguments.From(local.cursor)).AsArray();

                local.length = local.keys.GetLength();
                local.i      = 0;
                local.stage  = 2;
                return;
            }
            if (local.stage == 2) // For loop
            {
                if (local.i < local.length)
                {
                    local.stage = 3;
                }
                else
                {
                    local.stage = 4;
                }
            }
            if (local.stage == 3) // For contents
            {
                if (state.calleeReturned)
                {
                    local.i++;
                    local.stage = 2;
                    return;
                }

                var p = local.keys.GetOwnProperty(TypeConverter.ToString(local.i)).Value.AsStringWithoutTypeCheck();

                if (local.processedKeys.Contains(p))
                {
                    local.i++;
                    local.stage = 2;
                    return;
                }

                local.processedKeys.Add(p);

                // collection might be modified by inner statement
                if (local.cursor.GetOwnProperty(p) == PropertyDescriptor.Undefined)
                {
                    local.i++;
                    local.stage = 2;
                    return;
                }

                var value = local.cursor.GetOwnProperty(p);
                if (!value.Enumerable)
                {
                    local.i++;
                    local.stage = 2;
                    return;
                }

                _engine.PutValue(local.varRef, p);
                local.i++;
                local.stage = 2;
                return;
            }
            if (local.stage == 4) // after for loop
            {
                local.cursor = local.cursor.Prototype;
                local.stage  = 0;
                return;
            }
        }