private JsValue SetValue()
            {
                // slower version
                var lref = _left.Evaluate() as Reference ?? ExceptionHelper.ThrowReferenceError <Reference>(_engine);

                lref.AssertValid(_engine);

                var rval = _right.GetValue();

                _engine.PutValue(lref, rval);
                _engine._referencePool.Return(lref);
                return(rval);
            }
Esempio n. 2
0
        protected override object EvaluateInternal()
        {
            string  baseReferenceName = null;
            JsValue baseValue         = null;
            var     isStrictModeCode  = StrictModeScope.IsStrictModeCode;

            if (_objectIdentifierExpression != null)
            {
                baseReferenceName = _objectIdentifierExpression._expressionName.Key.Name;
                var strict = isStrictModeCode;
                var env    = _engine.ExecutionContext.LexicalEnvironment;
                LexicalEnvironment.TryGetIdentifierEnvironmentWithBindingValue(
                    env,
                    _objectIdentifierExpression._expressionName,
                    strict,
                    out _,
                    out baseValue);
            }
            else if (_objectThisExpression != null)
            {
                baseValue = _objectThisExpression.GetValue();
            }

            if (baseValue is null)
            {
                // fast checks failed
                var baseReference = _objectExpression.Evaluate();
                if (baseReference is Reference reference)
                {
                    baseReferenceName = reference.GetReferencedName().ToString();
                    baseValue         = _engine.GetValue(reference, false);
                    _engine._referencePool.Return(reference);
                }
                else
                {
                    baseValue = _engine.GetValue(baseReference, false);
                }
            }

            var property = _determinedProperty ?? _propertyExpression.GetValue();

            TypeConverter.CheckObjectCoercible(_engine, baseValue, (MemberExpression)_expression, baseReferenceName);
            return(_engine._referencePool.Rent(baseValue, TypeConverter.ToPropertyKey(property), isStrictModeCode));
        }
            // https://262.ecma-international.org/5.1/#sec-11.13.1
            private ExpressionResult SetValue(EvaluationContext context)
            {
                // slower version
                var engine = context.Engine;
                var lref   = _left.Evaluate(context).Value as Reference;

                if (lref is null)
                {
                    ExceptionHelper.ThrowReferenceError(engine.Realm, "not a valid reference");
                }

                lref.AssertValid(engine.Realm);

                var rval = _right.GetValue(context).GetValueOrDefault();

                engine.PutValue(lref, rval);
                engine._referencePool.Return(lref);
                return(NormalCompletion(rval));
            }
Esempio n. 4
0
        private object UpdateNonIdentifier()
        {
            if (!(_argument.Evaluate() is Reference reference))
            {
                return(ExceptionHelper.ThrowTypeError <object>(_engine, "Invalid left-hand side expression"));
            }

            reference.AssertValid(_engine);

            var value     = _engine.GetValue(reference, false);
            var isInteger = value._type == InternalTypes.Integer;
            var newValue  = isInteger
                ? JsNumber.Create(value.AsInteger() + _change)
                : JsNumber.Create(TypeConverter.ToNumber(value) + _change);

            _engine.PutValue(reference, newValue);
            _engine._referencePool.Return(reference);

            return(_prefix
                ? newValue
                : (isInteger ? value : JsNumber.Create(TypeConverter.ToNumber(value))));
        }
        protected override object EvaluateInternal()
        {
            switch (_operator)
            {
            case UnaryOperator.Plus:
                var plusValue = _argument.GetValue();
                return(plusValue.IsInteger() && plusValue.AsInteger() != 0
                        ? plusValue
                        : JsNumber.Create(TypeConverter.ToNumber(plusValue)));

            case UnaryOperator.Minus:
                return(EvaluateMinus(_argument.GetValue()));

            case UnaryOperator.BitwiseNot:
                return(JsNumber.Create(~TypeConverter.ToInt32(_argument.GetValue())));

            case UnaryOperator.LogicalNot:
                return(!TypeConverter.ToBoolean(_argument.GetValue()) ? JsBoolean.True : JsBoolean.False);

            case UnaryOperator.Delete:
                var r = _argument.Evaluate() as Reference;
                if (r == null)
                {
                    return(JsBoolean.True);
                }

                if (r.IsUnresolvableReference())
                {
                    if (r.IsStrictReference())
                    {
                        ExceptionHelper.ThrowSyntaxError(_engine);
                    }

                    _engine._referencePool.Return(r);
                    return(JsBoolean.True);
                }

                if (r.IsPropertyReference())
                {
                    var o            = TypeConverter.ToObject(_engine, r.GetBase());
                    var deleteStatus = o.Delete(r.GetReferencedName());
                    if (!deleteStatus && r.IsStrictReference())
                    {
                        ExceptionHelper.ThrowTypeError(_engine);
                    }

                    _engine._referencePool.Return(r);
                    return(deleteStatus ? JsBoolean.True : JsBoolean.False);
                }

                if (r.IsStrictReference())
                {
                    ExceptionHelper.ThrowSyntaxError(_engine);
                }

                var bindings = r.GetBase().TryCast <EnvironmentRecord>();
                var property = r.GetReferencedName();
                _engine._referencePool.Return(r);

                return(bindings.DeleteBinding(property.ToString()) ? JsBoolean.True : JsBoolean.False);

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

            case UnaryOperator.TypeOf:
                var value = _argument.Evaluate();
                r = value as Reference;
                if (r != null)
                {
                    if (r.IsUnresolvableReference())
                    {
                        _engine._referencePool.Return(r);
                        return(JsString.UndefinedString);
                    }
                }

                var v = _argument.GetValue();

                if (v.IsUndefined())
                {
                    return(JsString.UndefinedString);
                }

                if (v.IsNull())
                {
                    return(JsString.ObjectString);
                }

                switch (v.Type)
                {
                case Types.Boolean: return(JsString.BooleanString);

                case Types.Number: return(JsString.NumberString);

                case Types.String: return(JsString.StringString);

                case Types.Symbol: return(JsString.SymbolString);
                }

                if (v.IsCallable)
                {
                    return(JsString.FunctionString);
                }

                return(JsString.ObjectString);

            default:
                return(ExceptionHelper.ThrowArgumentException <object>());
            }
        }
Esempio n. 6
0
        protected override ExpressionResult EvaluateInternal(EvaluationContext context)
        {
            JsValue actualThis        = null;
            string  baseReferenceName = null;
            JsValue baseValue         = null;
            var     isStrictModeCode  = StrictModeScope.IsStrictModeCode;

            var engine = context.Engine;

            if (_objectExpression is JintIdentifierExpression identifierExpression)
            {
                baseReferenceName = identifierExpression._expressionName.Key.Name;
                var strict = isStrictModeCode;
                var env    = engine.ExecutionContext.LexicalEnvironment;
                JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue(
                    env,
                    identifierExpression._expressionName,
                    strict,
                    out _,
                    out baseValue);
            }
            else if (_objectExpression is JintThisExpression thisExpression)
            {
                baseValue = thisExpression.GetValue(context).Value;
            }
            else if (_objectExpression is JintSuperExpression)
            {
                var env = (FunctionEnvironmentRecord)engine.ExecutionContext.GetThisEnvironment();
                actualThis = env.GetThisBinding();
                baseValue  = env.GetSuperBase();
            }

            if (baseValue is null)
            {
                // fast checks failed
                var baseReference = _objectExpression.Evaluate(context).Value;
                if (ReferenceEquals(Undefined.Instance, baseReference))
                {
                    return(NormalCompletion(Undefined.Instance));
                }
                if (baseReference is Reference reference)
                {
                    baseReferenceName = reference.GetReferencedName().ToString();
                    baseValue         = engine.GetValue(reference, false);
                    engine._referencePool.Return(reference);
                }
                else
                {
                    baseValue = engine.GetValue(baseReference, false);
                }
            }

            if (baseValue.IsNullOrUndefined() && (_memberExpression.Optional || _objectExpression._expression.IsOptional()))
            {
                return(NormalCompletion(Undefined.Instance));
            }

            var property = _determinedProperty ?? _propertyExpression.GetValue(context).Value;

            if (baseValue.IsNullOrUndefined())
            {
                // we can use base data types securely, object evaluation can mess things up
                var referenceName = property.IsPrimitive()
                    ? TypeConverter.ToString(property)
                    : _determinedProperty?.ToString() ?? baseReferenceName;

                TypeConverter.CheckObjectCoercible(engine, baseValue, _memberExpression.Property, referenceName);
            }

            // only convert if necessary
            var propertyKey = property.IsInteger() && baseValue.IsIntegerIndexedArray
                ? property
                : TypeConverter.ToPropertyKey(property);

            var rent = context.Engine._referencePool.Rent(baseValue, propertyKey, isStrictModeCode, thisValue: actualThis);

            return(new ExpressionResult(
                       ExpressionCompletionType.Reference,
                       rent,
                       _expression.Location));
        }
Esempio n. 7
0
        private JsValue UpdateNonIdentifier(EvaluationContext context)
        {
            var engine    = context.Engine;
            var reference = _argument.Evaluate(context).Value as Reference;

            if (reference is null)
            {
                ExceptionHelper.ThrowTypeError(engine.Realm, "Invalid left-hand side expression");
            }

            reference.AssertValid(engine.Realm);

            var value     = engine.GetValue(reference, false);
            var isInteger = value._type == InternalTypes.Integer;

            JsValue newValue = null;

            var operatorOverloaded = false;

            if (context.OperatorOverloadingAllowed)
            {
                if (JintUnaryExpression.TryOperatorOverloading(context, _argument.GetValue(context).Value, _change > 0 ? "op_Increment" : "op_Decrement", out var result))
                {
                    operatorOverloaded = true;
                    newValue           = result;
                }
            }

            if (!operatorOverloaded)
            {
                if (isInteger)
                {
                    newValue = JsNumber.Create(value.AsInteger() + _change);
                }
                else if (!value.IsBigInt())
                {
                    newValue = JsNumber.Create(TypeConverter.ToNumber(value) + _change);
                }
                else
                {
                    newValue = JsBigInt.Create(TypeConverter.ToBigInt(value) + _change);
                }
            }

            engine.PutValue(reference, newValue);
            engine._referencePool.Return(reference);

            if (_prefix)
            {
                return(newValue);
            }
            else
            {
                if (isInteger || operatorOverloaded)
                {
                    return(value);
                }

                if (!value.IsBigInt())
                {
                    return(JsNumber.Create(TypeConverter.ToNumber(value)));
                }

                return(JsBigInt.Create(value));
            }
        }