示例#1
0
        protected override object EvaluateInternal()
        {
            var rightValue = _right.GetValue();

            ProcessPatterns(_engine, _pattern, rightValue, null);
            return(rightValue);
        }
示例#2
0
        protected override ExpressionResult EvaluateInternal(EvaluationContext context)
        {
            var engine = context.Engine;
            var tagger = engine.GetValue(_tagIdentifier.GetValue(context)) as ICallable;

            if (tagger is null)
            {
                ExceptionHelper.ThrowTypeError(engine.Realm, "Argument must be callable");
            }

            var expressions = _quasi._expressions;

            var args = engine._jsValueArrayPool.RentArray(expressions.Length + 1);

            var template = GetTemplateObject(context);

            args[0] = template;

            for (int i = 0; i < expressions.Length; ++i)
            {
                args[i + 1] = expressions[i].GetValue(context).Value;
            }

            var result = tagger.Call(JsValue.Undefined, args);

            engine._jsValueArrayPool.ReturnArray(args);

            return(NormalCompletion(result));
        }
示例#3
0
        protected override ExpressionResult EvaluateInternal(EvaluationContext context)
        {
            var engine = context.Engine;

            // todo: optimize by defining a common abstract class or interface
            var jsValue = _calleeExpression.GetValue(context).Value;

            JsValue[] arguments;
            if (_jintArguments.Length == 0)
            {
                arguments = Array.Empty <JsValue>();
            }
            else if (_hasSpreads)
            {
                arguments = BuildArgumentsWithSpreads(context, _jintArguments);
            }
            else
            {
                arguments = engine._jsValueArrayPool.RentArray(_jintArguments.Length);
                BuildArguments(context, _jintArguments, arguments);
            }

            if (!jsValue.IsConstructor)
            {
                ExceptionHelper.ThrowTypeError(engine.Realm, _calleeExpression.SourceText + " is not a constructor");
            }

            // construct the new instance using the Function's constructor method
            var instance = engine.Construct(jsValue, arguments, jsValue, _calleeExpression);

            engine._jsValueArrayPool.ReturnArray(arguments);

            return(NormalCompletion(instance));
        }
            internal static JsValue AssignToIdentifier(
                Engine engine,
                JintIdentifierExpression left,
                JintExpression right,
                bool hasEvalOrArguments)
            {
                var env    = engine.ExecutionContext.LexicalEnvironment;
                var strict = StrictModeScope.IsStrictModeCode;

                if (LexicalEnvironment.TryGetIdentifierEnvironmentWithBindingValue(
                        env,
                        left._expressionName,
                        strict,
                        out var environmentRecord,
                        out _))
                {
                    if (strict && hasEvalOrArguments)
                    {
                        ExceptionHelper.ThrowSyntaxError(engine);
                    }

                    var rval = right.GetValue().Clone();

                    if (right._expression.IsFunctionWithName())
                    {
                        ((FunctionInstance)rval).SetFunctionName(left._expressionName.StringValue);
                    }

                    environmentRecord.SetMutableBinding(left._expressionName, rval, strict);
                    return(rval);
                }

                return(null);
            }
        protected override object EvaluateInternal()
        {
            JsValue[] arguments;
            if (_jintArguments.Length == 0)
            {
                arguments = Array.Empty <JsValue>();
            }
            else if (_hasSpreads)
            {
                arguments = BuildArgumentsWithSpreads(_jintArguments);
            }
            else
            {
                arguments = _engine._jsValueArrayPool.RentArray(_jintArguments.Length);
                BuildArguments(_jintArguments, arguments);
            }

            // todo: optimize by defining a common abstract class or interface
            var jsValue = _calleeExpression.GetValue();

            if (!(jsValue is IConstructor callee))
            {
                return(ExceptionHelper.ThrowTypeError <object>(_engine, "The object can't be used as constructor."));
            }

            // construct the new instance using the Function's constructor method
            var instance = callee.Construct(arguments, jsValue);

            _engine._jsValueArrayPool.ReturnArray(arguments);

            return(instance);
        }
示例#6
0
        private JsValue EvaluateConstantOrExpression(EvaluationContext context)
        {
            var left = _left.GetValue(context).Value;

            return(!left.IsNullOrUndefined()
                ? left
                : _constant ?? _right.GetValue(context).Value);
        }
 internal void GetValueAndCheckIterator(out JsValue instance, out IIterator iterator)
 {
     instance = _argument.GetValue();
     if (instance is null || !instance.TryGetIterator(_engine, out iterator))
     {
         iterator = null;
         ExceptionHelper.ThrowTypeError(_engine, _argumentName + " is not iterable");
     }
 }
示例#8
0
 internal void GetValueAndCheckIterator(EvaluationContext context, out JsValue instance, out IteratorInstance iterator)
 {
     instance = _argument.GetValue(context).Value;
     if (instance is null || !instance.TryGetIterator(context.Engine.Realm, out iterator))
     {
         iterator = null;
         ExceptionHelper.ThrowTypeError(context.Engine.Realm, _argumentName + " is not iterable");
     }
 }
        private JsValue NamedEvaluation(EvaluationContext context, JintExpression expression)
        {
            var rval = expression.GetValue(context).Value;

            if (expression._expression.IsAnonymousFunctionDefinition() && _left._expression.Type == Nodes.Identifier)
            {
                ((FunctionInstance)rval).SetFunctionName(((Identifier)_left._expression).Name);
            }

            return(rval);
        }
            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);
            }
示例#11
0
        protected override object EvaluateInternal()
        {
            var left = _left.GetValue();

            if (left is JsBoolean b && !b._value)
            {
                return(b);
            }

            if (!TypeConverter.ToBoolean(left))
            {
                return(left);
            }

            return(_right.GetValue());
        }
示例#12
0
        protected override ExpressionResult EvaluateInternal(EvaluationContext context)
        {
            var left = _left.GetValue(context).Value;

            if (left is JsBoolean b && !b._value)
            {
                return(NormalCompletion(b));
            }

            if (!TypeConverter.ToBoolean(left))
            {
                return(NormalCompletion(left));
            }

            return(_right.GetValue(context));
        }
示例#13
0
        protected override ExpressionResult EvaluateInternal(EvaluationContext context)
        {
            var rightValue = _right.GetValue(context);

            if (rightValue.IsAbrupt())
            {
                return(rightValue);
            }

            var completion = ProcessPatterns(context, _pattern, rightValue.Value, null);

            if (completion.IsAbrupt())
            {
                return(completion);
            }

            return(rightValue);
        }
示例#14
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));
        }
示例#15
0
            // 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));
            }
示例#16
0
            internal static ExpressionResult?AssignToIdentifier(
                EvaluationContext context,
                JintIdentifierExpression left,
                JintExpression right,
                bool hasEvalOrArguments)
            {
                var engine = context.Engine;
                var env    = engine.ExecutionContext.LexicalEnvironment;
                var strict = StrictModeScope.IsStrictModeCode;

                if (JintEnvironment.TryGetIdentifierEnvironmentWithBinding(
                        env,
                        left._expressionName,
                        out var environmentRecord))
                {
                    if (strict && hasEvalOrArguments)
                    {
                        ExceptionHelper.ThrowSyntaxError(engine.Realm);
                    }

                    var completion = right.GetValue(context);
                    if (completion.IsAbrupt())
                    {
                        return(completion);
                    }

                    var rval = completion.Value.Clone();

                    if (right._expression.IsFunctionDefinition())
                    {
                        ((FunctionInstance)rval).SetFunctionName(left._expressionName.StringValue);
                    }

                    environmentRecord.SetMutableBinding(left._expressionName, rval, strict);
                    return(new Completion(CompletionType.Normal, rval, default));
                }

                return(null);
            }
        protected override object EvaluateInternal()
        {
            var tagger = _engine.GetValue(_tagIdentifier.GetValue()) as ICallable
                         ?? ExceptionHelper.ThrowTypeError <ICallable>(_engine, "Argument must be callable");

            var expressions = _quasi._expressions;

            var args = _engine._jsValueArrayPool.RentArray((expressions.Length + 1));

            var template = GetTemplateObject();

            args[0] = template;

            for (int i = 0; i < expressions.Length; ++i)
            {
                args[i + 1] = expressions[i].GetValue();
            }

            var result = tagger.Call(JsValue.Undefined, args);

            _engine._jsValueArrayPool.ReturnArray(args);

            return(result);
        }
示例#18
0
 protected override ExpressionResult EvaluateInternal(EvaluationContext context)
 {
     return(TypeConverter.ToBoolean(_test.GetValue(context).Value)
         ? _consequent.GetValue(context)
         : _alternate.GetValue(context));
 }
 protected override object EvaluateInternal()
 {
     return(TypeConverter.ToBoolean(_test.GetValue())
         ? _consequent.GetValue()
         : _alternate.GetValue());
 }
        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>());
            }
        }
示例#21
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));
            }
        }
示例#22
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));
        }