Example #1
0
        public override JSValue Evaluate(Context context)
        {
            var       temp         = _left.Evaluate(context);
            var       targetObject = context._objectSource;
            ICallable callable     = null;
            Function  func         = null;

            if (temp._valueType >= JSValueType.Object)
            {
                if (temp._valueType == JSValueType.Function)
                {
                    func     = temp._oValue as Function;
                    callable = func;
                }

                if (func == null)
                {
                    callable = temp._oValue as ICallable ?? temp.Value as ICallable;
                    if (callable == null)
                    {
                        if (temp.Value is Proxy typeProxy)
                        {
                            callable = typeProxy.PrototypeInstance as ICallable;
                        }
                    }
                }
            }

            if (callable == null)
            {
                foreach (var t in _arguments)
                {
                    context._objectSource = null;
                    t.Evaluate(context);
                }

                context._objectSource = null;


                if (targetObject.Is <Function>())
                {
                    ExceptionHelper.ThrowTypeError($"'{_left.LeftOperand}' is a function, '{_left}' is not defined.");
                }
                else
                {
                    if (temp.ValueType == JSValueType.NotExistsInObject || temp.ValueType == JSValueType.NotExists)
                    {
                        ExceptionHelper.ThrowTypeError($"'{((Property)_left).FieldName}' not found in '{_left.LeftOperand}'");
                    }
                    if (temp.IsNull)
                    {
                        ExceptionHelper.ThrowTypeError($"{((Property)_left).FieldName} is null in '{_left.LeftOperand}'");
                    }
                    if (temp.Exists && temp.ValueType == JSValueType.Undefined)
                    {
                        ExceptionHelper.ThrowTypeError($"{((Property)_left).FieldName} has type 'UNDEFINED' in '{_left.LeftOperand}'");
                    }
                    ExceptionHelper.ThrowTypeError($"'<{temp.ValueType}>{((Property)_left).FieldName}' is not a function.");
                }

                return(null);
            }

            if (func == null)
            {
                checkStack();
                Context.CurrentGlobalContext._callDepth++;
                try
                {
                    switch (_callMode)
                    {
                    case CallMode.Construct:
                        return(callable.Construct(Tools.CreateArguments(_arguments, context)));

                    case CallMode.Super:
                        return(callable.Construct(targetObject, Tools.CreateArguments(_arguments, context)));

                    default:
                        return(callable.Call(targetObject, Tools.CreateArguments(_arguments, context)));
                    }
                }
                finally
                {
                    Context.CurrentGlobalContext._callDepth--;
                }
            }

            if (allowTCO &&
                _callMode == 0 &&
                (func._functionDefinition.kind != FunctionKind.Generator) &&
                (func._functionDefinition.kind != FunctionKind.MethodGenerator) &&
                (func._functionDefinition.kind != FunctionKind.AnonymousGenerator) &&
                context._owner != null &&
                func == context._owner._oValue)
            {
                tailCall(context, func);
                context._objectSource = targetObject;
                return(JSValue.undefined);
            }

            context._objectSource = null;

            checkStack();
            Context.CurrentGlobalContext._callDepth++;
            try
            {
                if (_callMode == CallMode.Construct)
                {
                    targetObject = null;
                }

                if ((temp._attributes & JSValueAttributesInternal.Eval) != 0)
                {
                    return(callEval(context));
                }

                return(func.InternalInvoke(targetObject, _arguments, context, withSpread, _callMode != 0));
            }
            finally
            {
                Context.CurrentGlobalContext._callDepth--;
            }
        }
Example #2
0
        public override JSValue Evaluate(Context context)
        {
            var       temp         = _left.Evaluate(context);
            JSValue   targetObject = context._objectSource;
            ICallable callable     = null;
            Function  func         = null;

            if (temp._valueType >= JSValueType.Object)
            {
                if (temp._valueType == JSValueType.Function)
                {
                    func     = temp._oValue as Function;
                    callable = func;
                }

                if (func == null)
                {
                    callable = temp._oValue as ICallable;
                    if (callable == null)
                    {
                        callable = temp.Value as ICallable;
                    }
                    if (callable == null)
                    {
                        var typeProxy = temp.Value as Proxy;
                        if (typeProxy != null)
                        {
                            callable = typeProxy.PrototypeInstance as ICallable;
                        }
                    }
                }
            }

            if (callable == null)
            {
                for (int i = 0; i < this._arguments.Length; i++)
                {
                    context._objectSource = null;
                    this._arguments[i].Evaluate(context);
                }

                context._objectSource = null;

                // Аргументы должны быть вычислены даже если функция не существует.
                ExceptionHelper.ThrowTypeError(_left.ToString() + " is not a function");

                return(null);
            }
            else if (func == null)
            {
                checkStack();
                Context.CurrentGlobalContext._callDepth++;
                try
                {
                    switch (_callMode)
                    {
                    case CallMode.Construct:
                    {
                        return(callable.Construct(Tools.CreateArguments(_arguments, context)));
                    }

                    case CallMode.Super:
                    {
                        return(callable.Construct(targetObject, Tools.CreateArguments(_arguments, context)));
                    }

                    default:
                        return(callable.Call(targetObject, Tools.CreateArguments(_arguments, context)));
                    }
                }
                finally
                {
                    Context.CurrentGlobalContext._callDepth--;
                }
            }
            else
            {
                if (allowTCO &&
                    _callMode == 0 &&
                    (func._functionDefinition.kind != FunctionKind.Generator) &&
                    (func._functionDefinition.kind != FunctionKind.MethodGenerator) &&
                    (func._functionDefinition.kind != FunctionKind.AnonymousGenerator) &&
                    context._owner != null &&
                    func == context._owner._oValue)
                {
                    tailCall(context, func);
                    context._objectSource = targetObject;
                    return(JSValue.undefined);
                }
                else
                {
                    context._objectSource = null;
                }

                checkStack();
                Context.CurrentGlobalContext._callDepth++;
                try
                {
                    if (_callMode == CallMode.Construct)
                    {
                        targetObject = null;
                    }

                    if ((temp._attributes & JSValueAttributesInternal.Eval) != 0)
                    {
                        return(callEval(context));
                    }

                    return(func.InternalInvoke(targetObject, _arguments, context, withSpread, _callMode != 0));
                }
                finally
                {
                    Context.CurrentGlobalContext._callDepth--;
                }
            }
        }
Example #3
0
        public override JSValue Evaluate(Context context)
        {
#if DEBUG
            if (context._callDepth >= 800)
#else
            if (context._callDepth >= 1000)
#endif
            { ExceptionHelper.Throw(new RangeError("Stack overflow."), this, context); }

            var function = _left.Evaluate(context);

            JSValue targetObject = context._objectSource;

            ICallable callable = null;
            Function  func     = null;

            if (function._valueType == JSValueType.Function)
            {
                func     = function._oValue as Function;
                callable = func;
            }

            if (func == null)
            {
                callable = function._oValue as ICallable;
                if (callable == null)
                {
                    callable = function.Value as ICallable;
                }

                if (callable == null)
                {
                    var typeProxy = function.Value as Proxy;
                    if (typeProxy != null)
                    {
                        callable = typeProxy.PrototypeInstance as ICallable;
                    }
                }

                if (callable == null)
                {
                    if (OptionalChaining)
                    {
                        return(JSValue.undefined);
                    }

                    for (int i = 0; i < _arguments.Length; i++)
                    {
                        context._objectSource = null;
                        _arguments[i].Evaluate(context);
                    }

                    context._objectSource = null;

                    // Аргументы должны быть вычислены даже если функция не существует.
                    ExceptionHelper.ThrowTypeError(_left.ToString() + " is not a function", this, context);

                    return(null);
                }
            }

            if (func == null)
            {
                switch (_callMode)
                {
                case CallMode.Construct:
                    return(callable.Construct(Tools.CreateArguments(_arguments, context)));

                case CallMode.Super:
                    return(callable.Construct(targetObject, Tools.CreateArguments(_arguments, context)));

                default:
                    return(callable.Call(targetObject, Tools.CreateArguments(_arguments, context)));
                }
            }

            if (_allowTCO &&
                _callMode == 0 &&
                (func._functionDefinition.kind != FunctionKind.Generator) &&
                (func._functionDefinition.kind != FunctionKind.MethodGenerator) &&
                (func._functionDefinition.kind != FunctionKind.AnonymousGenerator) &&
                context._owner != null &&
                func == context._owner._oValue)
            {
                tailCall(context, func);
                context._objectSource = targetObject;
                return(JSValue.undefined);
            }
            else
            {
                context._objectSource = null;
            }

            if (_callMode == CallMode.Construct)
            {
                targetObject = null;
            }

            if ((function._attributes & JSValueAttributesInternal.Eval) != 0)
            {
                return(callEval(context));
            }

            return(func.InternalInvoke(targetObject, _arguments, context, _withSpread, _callMode != 0));
        }