예제 #1
0
        private static Completion Parse(IValue thisObj, IReadOnlyList <IValue> arguments)
        {
            var argComp = arguments.At(0);

            if (argComp.IsAbrupt())
            {
                return(argComp);
            }
            var dateComp = argComp.value !.ToJsString();

            if (dateComp.IsAbrupt())
            {
                return(dateComp);
            }
            var date = (dateComp.value as StringValue) !.@string;

            if (!DateTime.TryParseExact(date, DefaultFormats, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out var result))
            {
                if (!DateTime.TryParseExact(date, SecondaryFormats, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result))
                {
                    if (!DateTime.TryParse(date, Interpreter.Instance().Culture, DateTimeStyles.AdjustToUniversal, out result))
                    {
                        if (!DateTime.TryParse(date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result))
                        {
                            // unrecognized dates should return NaN (15.9.4.2)
                            return(Completion.NormalCompletion(NumberValue.DoubleNaN));
                        }
                    }
                }
            }

            return(Completion.NormalCompletion(new NumberValue(FromDateTime(result))));
        }
예제 #2
0
        private static Completion getOwnPropertyDescriptor(IValue @this, IReadOnlyList <IValue> arguments)
        {
            var argCheck = Utils.CheckArguments(arguments, 2);

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

            var obj = arguments[0].ToObject();

            if (obj.IsAbrupt())
            {
                return(obj);
            }
            var key = arguments[1].ToPropertyKey();

            if (key.IsAbrupt())
            {
                return(key);
            }
            var desc = (obj.value as Object) !.GetOwnProperty(key.Other !);

            if (desc.IsAbrupt())
            {
                return(desc);
            }
            return(Completion.NormalCompletion(desc.Other?.ToObject() as IValue ?? UndefinedValue.Instance));
        }
예제 #3
0
        public static Completion CopyDataProperties(Object target, IValue source, IReadOnlyList <string> excludedItems)
        {
            if (source is UndefinedValue || source is NullValue)
            {
                return(Completion.NormalCompletion(target));
            }
            var from = (source.ToObject().value as Object) !;
            IReadOnlyList <string> keys = from.OwnPropertyKeys();

            foreach (var nextKey in keys)
            {
                var excluded = excludedItems.Contains(nextKey);
                if (!excluded)
                {
                    var descComp = from.GetOwnProperty(nextKey);
                    if (descComp.IsAbrupt())
                    {
                        return(descComp);
                    }
                    var desc = descComp.Other;
                    if (desc != null && desc.Enumerable.HasValue && desc.Enumerable.Value)
                    {
                        var propValue = from.Get(nextKey);
                        if (propValue.IsAbrupt())
                        {
                            return(propValue);
                        }
                        CreateDataProperty(target, nextKey, propValue.value !);
                    }
                }
            }
            return(Completion.NormalCompletion(target));
        }
예제 #4
0
        private static Completion charAt(IValue thisValue, IReadOnlyList <IValue> arguments)
        {
            var O = thisValue.RequireObjectCoercible();

            if (O.IsAbrupt())
            {
                return(O);
            }
            var sComp = O.value !.ToJsString();

            if (sComp.IsAbrupt())
            {
                return(sComp);
            }
            var S            = (sComp.value as StringValue) !.@string;
            var pos          = arguments.At(0, UndefinedValue.Instance);
            var positionComp = pos.ToInteger();

            if (positionComp.IsAbrupt())
            {
                return(positionComp);
            }
            var position = positionComp.Other;
            var size     = S.Length;

            if (position < 0 || position >= size)
            {
                return(Completion.NormalCompletion(StringValue.Empty));
            }
            return(Completion.NormalCompletion(new StringValue(S.Substring(position, 1))));
        }
예제 #5
0
        public override Completion InternalCall(IValue @this, IReadOnlyList <IValue> arguments)
        {
            if (FunctionKind == FunctionKind.ClassConstructor)
            {
                throw new InvalidOperationException("FunctionObject.Call: Spec 9.2.1 step 2");
            }
            var callerContext = Interpreter.Instance().RunningExecutionContext();
            var calleeContext = PrepareForOrdinaryCall(UndefinedValue.Instance);

            if (Interpreter.Instance().RunningExecutionContext() != calleeContext)
            {
                throw new InvalidOperationException("FunctionObject.Call: FunctionObject.PrepareForOrdinaryCall did not perform as expected.");
            }
            OrdinaryCallBindThis(calleeContext, @this);
            var result = OrdinaryCallEvaluateBody(arguments);

            Interpreter.Instance().PopExecutionStack(calleeContext);
            if (callerContext != Interpreter.Instance().RunningExecutionContext())
            {
                throw new InvalidOperationException("Interpreter.PopExecutionStack did not perform as expected.");
            }
            if (result.completionType == CompletionType.Return)
            {
                return(Completion.NormalCompletion(result.value));
            }
            if (result.IsAbrupt())
            {
                return(result);
            }
            return(Completion.NormalCompletion(UndefinedValue.Instance));
        }
        public Completion CreateGlobalVarBinding(string n, bool d)
        {
            var hasProperty = ObjectRecord.BindingObject.HasOwnProperty(n);

            if (hasProperty.IsAbrupt())
            {
                return(hasProperty);
            }
            var extensible = ObjectRecord.BindingObject.IsExtensible;

            if (hasProperty.Other == false && extensible == true)
            {
                var comp = ObjectRecord.CreateMutableBinding(n, d);
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
                comp = ObjectRecord.InitializeBinding(n, UndefinedValue.Instance);
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
            }
            if (!VarNames.Contains(n))
            {
                VarNames.Add(n);
            }
            return(Completion.NormalCompletion());
        }
예제 #7
0
 public override Completion InternalConstruct(IReadOnlyList <IValue> arguments, Object?newTarget)
 {
     if (arguments.Count == 0)
     {
         return(Completion.NormalCompletion(Utils.ObjectCreate(Interpreter.Instance().CurrentRealm().Intrinsics.ObjectPrototype)));
     }
     return(InternalCall(this, arguments));
 }
예제 #8
0
 public static Completion At(this IReadOnlyList <IValue> arguments, int index)
 {
     if (arguments.Count <= index)
     {
         return(Completion.ThrowTypeError($"At least {index + 1} arguments are required"));
     }
     return(Completion.NormalCompletion(arguments[index]));
 }
예제 #9
0
 private Completion OrdinaryCallEvaluateBody(IReadOnlyList <IValue> arguments)
 {
     if (Code != null)
     {
         return(Code.EvaluateBody(this, arguments));
     }
     return(Completion.NormalCompletion());
 }
예제 #10
0
 public override Completion InternalCall(IValue thisValue, IReadOnlyList <IValue> arguments)
 {
     if (arguments.Count == 0)
     {
         return(Completion.NormalCompletion(NumberValue.PositiveZero));
     }
     return(arguments[0].ToNumber());
 }
예제 #11
0
 public override Completion CreateMutableBinding(string name, bool deletable)
 {
     if (bindings.ContainsKey(name))
     {
         throw new InvalidOperationException("Spec 8.1.1.1.2 step 2");
     }
     bindings.Add(name, BindingRecord.Mutable(canDelete: deletable));
     return(Completion.NormalCompletion());
 }
예제 #12
0
 public override Completion CreateImmutableBinding(string name, bool strict)
 {
     if (bindings.ContainsKey(name))
     {
         throw new InvalidOperationException("Spec 8.1.1.1.3 step 2");
     }
     bindings.Add(name, BindingRecord.Immutable(strict: strict));
     return(Completion.NormalCompletion());
 }
예제 #13
0
 public override Completion InitializeBinding(string name, IValue value)
 {
     if (!bindings.ContainsKey(name) || bindings[name].Value != null)
     {
         throw new InvalidOperationException("Spec 8.1.1.1.4 step 2");
     }
     bindings[name].Value = value;
     return(Completion.NormalCompletion());
 }
예제 #14
0
        public override Completion InternalConstruct(IReadOnlyList <IValue> arguments, Object?newTarget)
        {
            var    callerContext = Interpreter.Instance().RunningExecutionContext();
            IValue?thisArgument  = null;

            if (ConstructorKind == ConstructorKind.Base)
            {
                var thisComp = Utils.OrdinaryCreateFromConstructor(newTarget, i => i.ObjectPrototype);
                if (thisComp.IsAbrupt())
                {
                    return(thisComp);
                }
                thisArgument = thisComp.value;
            }
            ExecutionContext calleeContext = PrepareForOrdinaryCall(newTarget);

            if (calleeContext != Interpreter.Instance().RunningExecutionContext())
            {
                throw new InvalidOperationException("FunctionObject.PrepareForOrdinaryCall did not perform as expected.");
            }
            if (ConstructorKind == ConstructorKind.Base)
            {
                OrdinaryCallBindThis(calleeContext, thisArgument);
            }
            var constructorEnv = calleeContext.LexicalEnvironment;
            var envRec         = (constructorEnv.EnvironmentRecord as FunctionEnvironmentRecord) !;
            var result         = OrdinaryCallEvaluateBody(arguments);

            Interpreter.Instance().PopExecutionStack(calleeContext);
            if (callerContext != Interpreter.Instance().RunningExecutionContext())
            {
                throw new InvalidOperationException("Interpreter.PopExecutionStack did not perform as expected.");
            }
            if (result.completionType == CompletionType.Return)
            {
                if (result.value is Object)
                {
                    return(Completion.NormalCompletion(result.value));
                }
                if (ConstructorKind == ConstructorKind.Base)
                {
                    return(Completion.NormalCompletion(thisArgument));
                }
                if (!(result.value is UndefinedValue))
                {
                    throw new InvalidCastException("FunctionObject.InternalConstruct: Spec 9.2.2 step 13c");
                }
            }
            else if (result.IsAbrupt())
            {
                return(result);
            }
            return(envRec.GetThisBinding());
        }
 public Completion GetSuperBase()
 {
     if (HomeObject == UndefinedValue.Instance)
     {
         return(Completion.NormalCompletion(UndefinedValue.Instance));
     }
     if (!(HomeObject is Object o))
     {
         throw new InvalidOperationException("Spec 8.1.1.3.5 step 4");
     }
     return(o.GetPrototypeOf());
 }
 public Completion GetThisBinding()
 {
     if (ThisBindingStatus == ThisBindingStatus.Lexical)
     {
         throw new InvalidOperationException("Spec 8.1.1.3.4 step 2");
     }
     if (ThisBindingStatus == ThisBindingStatus.Uninitialized)
     {
         return(Completion.ThrowReferenceError("'this' value is not initialized"));
     }
     return(Completion.NormalCompletion(ThisValue));
 }
예제 #17
0
 public static Completion toString(IValue @this, IReadOnlyList <IValue> arguments)
 {
     if (@this is StringValue)
     {
         return(Completion.NormalCompletion(@this));
     }
     if (@this is StringObject s)
     {
         return(Completion.NormalCompletion(s.value));
     }
     return(Completion.ThrowTypeError("Must be called on a string"));
 }
예제 #18
0
 public override Completion GetBindingValue(string name, bool strict)
 {
     if (!bindings.ContainsKey(name))
     {
         throw new InvalidOperationException("Spec 8.1.1.1.6 step 2");
     }
     if (bindings[name].Value == null)
     {
         return(Completion.ThrowReferenceError($"binding {name} does not exist."));
     }
     return(Completion.NormalCompletion(bindings[name].Value));
 }
예제 #19
0
        public override Completion InternalConstruct(IReadOnlyList <IValue> arguments, Object?newTarget)
        {
            var booleanLiteral = InternalCall(UndefinedValue.Instance, arguments);

            if (booleanLiteral.IsAbrupt())
            {
                return(booleanLiteral);
            }
            var O = new BooleanObject((booleanLiteral.value as BooleanValue) !);

            return(Completion.NormalCompletion(O));
        }
예제 #20
0
 public static Completion valueOf(IValue @this, IReadOnlyList <IValue> arguments)
 {
     if (!(@this is DateObject d))
     {
         return(Completion.ThrowTypeError("this is not a Date object"));
     }
     if (double.IsNaN(d.PrimitiveValue))
     {
         return(Completion.NormalCompletion(new StringValue("Invalid Date")));
     }
     return(Completion.NormalCompletion(new NumberValue(d.PrimitiveValue)));
 }
예제 #21
0
        internal static Completion OrdinaryCreateFromConstructor(Object?constructor, Func <Intrinsics, Object> intrinsicDefaultProto)
        {
            var protoComp = GetPrototypeFromConstructor(constructor, intrinsicDefaultProto);

            if (protoComp.IsAbrupt())
            {
                return(protoComp);
            }
            var proto = protoComp.value !;

            return(Completion.NormalCompletion(ObjectCreate(proto)));
        }
예제 #22
0
        public static Completion getTimeZoneOffset(IValue @this, IReadOnlyList <IValue> arguments)
        {
            if (!(@this is DateObject d))
            {
                return(Completion.ThrowTypeError("this is not a Date object"));
            }
            var t = d.PrimitiveValue;

            if (!IsFinite(t))
            {
                return(Completion.NormalCompletion(NumberValue.DoubleNaN));
            }
            return(Completion.NormalCompletion(new NumberValue((int)(t - LocalTime(t)) / MsPerMinute)));
        }
예제 #23
0
        public static Completion getMonth(IValue @this, IReadOnlyList <IValue> arguments)
        {
            if (!(@this is DateObject d))
            {
                return(Completion.ThrowTypeError("this is not a Date object"));
            }
            var t = d.PrimitiveValue;

            if (!IsFinite(t))
            {
                return(Completion.NormalCompletion(NumberValue.DoubleNaN));
            }
            return(Completion.NormalCompletion(new NumberValue(MonthFromTime(LocalTime(t)))));
        }
 public Completion BindThisValue(IValue value)
 {
     if (ThisBindingStatus == ThisBindingStatus.Lexical)
     {
         throw new InvalidOperationException("FunctionEnvironmentRecord.BindThisValue: ThisBindingStatus must not be Lexical");
     }
     if (ThisBindingStatus == ThisBindingStatus.Initialized)
     {
         return(Completion.ThrowReferenceError("'this' value is already initialized"));
     }
     ThisValue         = value;
     ThisBindingStatus = ThisBindingStatus.Initialized;
     return(Completion.NormalCompletion(value));
 }
예제 #25
0
        private static Completion isNaN(IValue thisValue, IReadOnlyList <IValue> arguments)
        {
            var number = arguments.At(0, UndefinedValue.Instance);

            if (!(number is NumberValue n))
            {
                return(Completion.NormalCompletion(BooleanValue.False));
            }
            if (double.IsNaN(n.number))
            {
                return(Completion.NormalCompletion(BooleanValue.True));
            }
            return(Completion.NormalCompletion(BooleanValue.False));
        }
예제 #26
0
        public Completion ResolveThisBinding()
        {
            var env = GetThisEnvironment();

            if (env is FunctionEnvironmentRecord functionEnvironmentRecord)
            {
                return(functionEnvironmentRecord.GetThisBinding());
            }
            if (env is GlobalEnvironmentRecord globalEnvironmentRecord)
            {
                return(Completion.NormalCompletion(globalEnvironmentRecord.GetThisBinding()));
            }

            throw new InvalidOperationException("env has no This Binding");
        }
예제 #27
0
        private static Completion ObjectDefineProperties(Object O, IValue Properties)
        {
            var propsComp = Properties.ToObject();

            if (propsComp.IsAbrupt())
            {
                return(propsComp);
            }
            var props       = propsComp.value as Object;
            var keys        = props !.OwnPropertyKeys();
            var descriptors = new List <(string, PropertyDescriptor)>();

            foreach (var nextKey in keys)
            {
                var propDesc = props.GetOwnProperty(nextKey);
                if (propDesc.IsAbrupt())
                {
                    return(propDesc);
                }
                if (propDesc.Other != null && propDesc.Other.Enumerable.GetValueOrDefault() == true)
                {
                    var descObj = props.Get(nextKey);
                    if (descObj.IsAbrupt())
                    {
                        return(descObj);
                    }
                    if (!(descObj.value is Object o))
                    {
                        return(Completion.ThrowTypeError("properties of the property argument must be objects."));
                    }
                    var desc = PropertyDescriptor.FromObject(o);
                    if (desc.IsAbrupt())
                    {
                        return(desc);
                    }
                    descriptors.Add((nextKey, desc.Other !));
                }
            }
            foreach (var(P, desc) in descriptors)
            {
                var comp = O.DefinePropertyOrThrow(P, desc);
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
            }
            return(Completion.NormalCompletion(O));
        }
예제 #28
0
        private Completion InitializeHostDefinedRealm()
        {
            var realm      = JSInterpreter.Realm.CreateRealm();
            var newContext = new ExecutionContext(realm);

            PushExecutionStack(newContext);
            realm.SetRealmGlobalObject(null, null);
            Completion globalObj = realm.SetDefaultGlobalBindings();

            if (globalObj.IsAbrupt())
            {
                return(globalObj);
            }
            // implementation-defined global object properties
            return(Completion.NormalCompletion());
        }
예제 #29
0
        public override Completion InternalCall(IValue thisValue, IReadOnlyList <IValue> arguments)
        {
            if (arguments.Count == 0)
            {
                return(Completion.NormalCompletion(StringValue.Empty));
            }

            var arg = arguments[0].ToJsString();

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

            return(Completion.NormalCompletion(arg.value));
        }
예제 #30
0
 private static Completion source(IValue thisValue, IReadOnlyList <IValue> arguments)
 {
     if (!(thisValue is Object))
     {
         return(Completion.ThrowTypeError("Not valid RegExp object"));
     }
     if (!(thisValue is RegExpObject o))
     {
         if (thisValue == Interpreter.Instance().CurrentRealm().Intrinsics.RegExpPrototype)
         {
             return(Completion.NormalCompletion(new StringValue("(?:)")));
         }
         return(Completion.ThrowTypeError("Not valid RegExp object"));
     }
     return(Completion.NormalCompletion(new StringValue(EscapeRegExpPattern(o.OriginalSource))));
 }