diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json index 37bc78d5b..f8bf7dfd4 100644 --- a/Jint.Tests.Test262/Test262Harness.settings.json +++ b/Jint.Tests.Test262/Test262Harness.settings.json @@ -1,5 +1,5 @@ { - "SuiteGitSha": "941813e1f0e64ae9a5c4c5c8075f49ff89b0c642", + "SuiteGitSha": "d62fa93c8f9ce5e687c0bbaa5d2b59670ab2ff60", //"SuiteDirectory": "//mnt/c/work/test262", "TargetPath": "./Generated", "Namespace": "Jint.Tests.Test262", @@ -10,7 +10,6 @@ "Atomics", "decorators", "explicit-resource-management", - "import-assertions", "iterator-helpers", "Math.sumPrecise", "regexp-lookbehind", diff --git a/Jint/Native/Array/ArrayOperations.cs b/Jint/Native/Array/ArrayOperations.cs index 07c771f28..a9618e813 100644 --- a/Jint/Native/Array/ArrayOperations.cs +++ b/Jint/Native/Array/ArrayOperations.cs @@ -79,7 +79,7 @@ public static ArrayOperations For(ObjectInstance instance, bool forWrite) public abstract JsValue Get(ulong index); public virtual JsValue[] GetAll( - Types elementTypes = Types.Undefined | Types.Null | Types.Boolean | Types.String | Types.Symbol | Types.Number | Types.Object, + Types elementTypes = Types.Undefined | Types.Null | Types.Boolean | Types.String | Types.Symbol | Types.Number | Types.BigInt | Types.Object, bool skipHoles = false) { uint writeIndex = 0; @@ -265,13 +265,15 @@ public override bool TryGetValue(ulong index, out JsValue value) public override JsValue Get(ulong index) => _target.Get((uint) index); - public override JsValue[] GetAll(Types elementTypes = Types.Undefined | Types.Null | Types.Boolean | Types.String | Types.Symbol | Types.Number | Types.Object, bool skipHoles = false) + public override JsValue[] GetAll( + Types elementTypes = Types.Empty | Types.Undefined | Types.Null | Types.Boolean | Types.String | Types.Number | Types.Symbol | Types.BigInt | Types.Object, + bool skipHoles = false) { var n = _target.GetLength(); if (_target._dense == null || _target._dense.Length < n) { - return base.GetAll(elementTypes); + return base.GetAll(elementTypes, skipHoles); } // optimized diff --git a/Jint/Native/JsTypedArray.cs b/Jint/Native/JsTypedArray.cs index 34ca77fbe..2df1b56d6 100644 --- a/Jint/Native/JsTypedArray.cs +++ b/Jint/Native/JsTypedArray.cs @@ -88,13 +88,10 @@ internal bool HasProperty(long numericIndex) /// public override bool HasProperty(JsValue property) { - if (property.IsString()) + var numericIndex = TypeConverter.CanonicalNumericIndexString(property); + if (numericIndex is not null) { - var numericIndex = TypeConverter.CanonicalNumericIndexString(property); - if (numericIndex is not null) - { - return IsValidIntegerIndex(numericIndex.Value); - } + return IsValidIntegerIndex(numericIndex.Value); } return base.HasProperty(property); @@ -162,39 +159,36 @@ public override bool Set(JsValue property, JsValue value, JsValue receiver) /// public override bool DefineOwnProperty(JsValue property, PropertyDescriptor desc) { - if (property.IsString()) + var numericIndex = TypeConverter.CanonicalNumericIndexString(property); + if (numericIndex is not null) { - var numericIndex = TypeConverter.CanonicalNumericIndexString(property); - if (numericIndex is not null) + if (!IsValidIntegerIndex(numericIndex.Value)) { - if (!IsValidIntegerIndex(numericIndex.Value)) - { - return false; - } - - if (desc.ConfigurableSet && !desc.Configurable) - { - return false; - } + return false; + } - if (desc.EnumerableSet && !desc.Enumerable) - { - return false; - } + if (desc is { ConfigurableSet: true, Configurable: false }) + { + return false; + } - if (desc.IsAccessorDescriptor()) - { - return false; - } + if (desc is { EnumerableSet: true, Enumerable: false }) + { + return false; + } - if (desc.WritableSet && !desc.Writable) - { - return false; - } + if (desc.IsAccessorDescriptor()) + { + return false; + } - IntegerIndexedElementSet(numericIndex.Value, desc.Value); - return true; + if (desc is { WritableSet: true, Writable: false }) + { + return false; } + + IntegerIndexedElementSet(numericIndex.Value, desc.Value); + return true; } return base.DefineOwnProperty(property, desc); diff --git a/Jint/Runtime/Debugger/DebugScope.cs b/Jint/Runtime/Debugger/DebugScope.cs index b04b54b26..04008ca8f 100644 --- a/Jint/Runtime/Debugger/DebugScope.cs +++ b/Jint/Runtime/Debugger/DebugScope.cs @@ -57,7 +57,7 @@ internal DebugScope(DebugScopeType type, Environment record, bool isTopLevel) /// Value of the binding public JsValue? GetBindingValue(string name) { - _record.TryGetBinding(new Environment.BindingName(name), out var result); + _record.TryGetBinding(new Environment.BindingName(name), strict: false, out var result); return result; } diff --git a/Jint/Runtime/Descriptors/Specialized/ClrAccessDescriptor.cs b/Jint/Runtime/Descriptors/Specialized/ClrAccessDescriptor.cs index bbc85c005..6ec1aae84 100644 --- a/Jint/Runtime/Descriptors/Specialized/ClrAccessDescriptor.cs +++ b/Jint/Runtime/Descriptors/Specialized/ClrAccessDescriptor.cs @@ -31,7 +31,7 @@ public ClrAccessDescriptor( private JsValue DoGet(JsValue n) { - return _env.TryGetBinding(_name, out var value) + return _env.TryGetBinding(_name, strict: true, out var value) ? value : JsValue.Undefined; } diff --git a/Jint/Runtime/Environments/DeclarativeEnvironment.cs b/Jint/Runtime/Environments/DeclarativeEnvironment.cs index 582a058d2..86f865a8d 100644 --- a/Jint/Runtime/Environments/DeclarativeEnvironment.cs +++ b/Jint/Runtime/Environments/DeclarativeEnvironment.cs @@ -23,7 +23,7 @@ public DeclarativeEnvironment(Engine engine, bool catchEnvironment = false) : ba internal sealed override bool HasBinding(Key name) => _dictionary is not null && _dictionary.ContainsKey(name); - internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out JsValue? value) + internal override bool TryGetBinding(BindingName name, bool strict, [NotNullWhen(true)] out JsValue? value) { if (_dictionary?.TryGetValue(name.Key, out var binding) == true) { diff --git a/Jint/Runtime/Environments/Environment.cs b/Jint/Runtime/Environments/Environment.cs index 66b738003..63dd15733 100644 --- a/Jint/Runtime/Environments/Environment.cs +++ b/Jint/Runtime/Environments/Environment.cs @@ -28,7 +28,7 @@ protected Environment(Engine engine) : base(InternalTypes.ObjectEnvironmentRecor internal abstract bool HasBinding(BindingName name); - internal abstract bool TryGetBinding(BindingName name, [NotNullWhen(true)] out JsValue? value); + internal abstract bool TryGetBinding(BindingName name, bool strict, [NotNullWhen(true)] out JsValue? value); /// /// Creates a new mutable binding in an environment record. diff --git a/Jint/Runtime/Environments/GlobalEnvironment.cs b/Jint/Runtime/Environments/GlobalEnvironment.cs index 8d45cf087..a918a8959 100644 --- a/Jint/Runtime/Environments/GlobalEnvironment.cs +++ b/Jint/Runtime/Environments/GlobalEnvironment.cs @@ -69,9 +69,9 @@ internal override bool HasBinding(BindingName name) return _global.HasProperty(name.Value); } - internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out JsValue? value) + internal override bool TryGetBinding(BindingName name, bool strict, [NotNullWhen(true)] out JsValue? value) { - if (_declarativeRecord._dictionary is not null && _declarativeRecord.TryGetBinding(name, out value)) + if (_declarativeRecord._dictionary is not null && _declarativeRecord.TryGetBinding(name, strict, out value)) { return true; } diff --git a/Jint/Runtime/Environments/JintEnvironment.cs b/Jint/Runtime/Environments/JintEnvironment.cs index 9a0af28fa..467920e0f 100644 --- a/Jint/Runtime/Environments/JintEnvironment.cs +++ b/Jint/Runtime/Environments/JintEnvironment.cs @@ -35,6 +35,7 @@ record = record._outerEnv; internal static bool TryGetIdentifierEnvironmentWithBindingValue( Environment env, Environment.BindingName name, + bool strict, [NotNullWhen(true)] out Environment? record, [NotNullWhen(true)] out JsValue? value) { @@ -43,12 +44,12 @@ record = env; if (env._outerEnv is null) { - return ((GlobalEnvironment) env).TryGetBinding(name, out value); + return ((GlobalEnvironment) env).TryGetBinding(name, strict, out value); } while (record is not null) { - if (record.TryGetBinding(name, out value)) + if (record.TryGetBinding(name, strict, out value)) { return true; } diff --git a/Jint/Runtime/Environments/ModuleEnvironment.cs b/Jint/Runtime/Environments/ModuleEnvironment.cs index afb5027e6..9e8b3445f 100644 --- a/Jint/Runtime/Environments/ModuleEnvironment.cs +++ b/Jint/Runtime/Environments/ModuleEnvironment.cs @@ -47,7 +47,7 @@ internal override JsValue GetBindingValue(Key name, bool strict) return base.GetBindingValue(name, strict); } - internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out JsValue? value) + internal override bool TryGetBinding(BindingName name, bool strict, [NotNullWhen(true)] out JsValue? value) { if (_importBindings.TryGetValue(name.Key, out var indirectBinding)) { @@ -55,7 +55,7 @@ internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out J return true; } - return base.TryGetBinding(name, out value); + return base.TryGetBinding(name, strict, out value); } /// diff --git a/Jint/Runtime/Environments/ObjectEnvironment.cs b/Jint/Runtime/Environments/ObjectEnvironment.cs index 7c1121f31..731b20a84 100644 --- a/Jint/Runtime/Environments/ObjectEnvironment.cs +++ b/Jint/Runtime/Environments/ObjectEnvironment.cs @@ -30,7 +30,7 @@ public ObjectEnvironment( internal override bool HasBinding(Key name) { var property = new JsString(name.Name); - var foundBinding = HasProperty(property); + var foundBinding = _bindingObject.HasProperty(property); if (!foundBinding) { @@ -47,7 +47,7 @@ internal override bool HasBinding(Key name) internal override bool HasBinding(BindingName name) { - var foundBinding = HasProperty(name.Value); + var foundBinding = _bindingObject.HasProperty(name.Value); if (!foundBinding) { @@ -62,15 +62,10 @@ internal override bool HasBinding(BindingName name) return !IsBlocked(name.Value); } - private bool HasProperty(JsValue property) - { - return _bindingObject.HasProperty(property); - } - - internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out JsValue? value) + internal override bool TryGetBinding(BindingName name, bool strict, [NotNullWhen(true)] out JsValue? value) { // we unwrap by name - if (!HasProperty(name.Value)) + if (!_bindingObject.HasProperty(name.Value)) { value = default; return false; @@ -83,6 +78,13 @@ internal override bool TryGetBinding(BindingName name, [NotNullWhen(true)] out J } value = _bindingObject.Get(name.Value); + + if (strict && value.IsUndefined() && !_bindingObject.HasProperty(name.Value)) + { + // data was deleted during reading of unscopable information, of course... + ExceptionHelper.ThrowReferenceNameError(_engine.Realm, name.Key); + } + return true; } diff --git a/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs index b86bdac31..e85f6ad3e 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs @@ -42,17 +42,19 @@ internal static JintExpression Build(AssignmentExpression expression) protected override object EvaluateInternal(EvaluationContext context) { var engine = context.Engine; + var strict = StrictModeScope.IsStrictModeCode; JsValue originalLeftValue; Reference lref; if (_leftIdentifier is not null && JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue( engine.ExecutionContext.LexicalEnvironment, _leftIdentifier.Identifier, + strict, out var identifierEnvironment, out var temp)) { originalLeftValue = temp; - lref = engine._referencePool.Rent(identifierEnvironment, _leftIdentifier.Identifier.Value, StrictModeScope.IsStrictModeCode, thisValue: null); + lref = engine._referencePool.Rent(identifierEnvironment, _leftIdentifier.Identifier.Value, strict, thisValue: null); } else { diff --git a/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs index 3eff83b4c..d33b5cab2 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs @@ -56,10 +56,12 @@ public override JsValue GetValue(EvaluationContext context) var engine = context.Engine; var env = engine.ExecutionContext.LexicalEnvironment; + var strict = StrictModeScope.IsStrictModeCode; if (JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue( env, identifier, + strict, out _, out var value)) { @@ -70,7 +72,7 @@ public override JsValue GetValue(EvaluationContext context) } else { - var reference = engine._referencePool.Rent(JsValue.Undefined, identifier.Value, StrictModeScope.IsStrictModeCode, thisValue: null); + var reference = engine._referencePool.Rent(JsValue.Undefined, identifier.Value, strict, thisValue: null); value = engine.GetValue(reference, returnReferenceToPool: true); } diff --git a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs index 92b567b38..db8b577a7 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs @@ -61,6 +61,7 @@ protected override object EvaluateInternal(EvaluationContext context) JsValue? baseValue = null; var engine = context.Engine; + var strict = StrictModeScope.IsStrictModeCode; if (_objectExpression is JintIdentifierExpression identifierExpression) { var identifier = identifierExpression.Identifier; @@ -69,6 +70,7 @@ protected override object EvaluateInternal(EvaluationContext context) JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue( env, identifier, + strict, out _, out baseValue); } @@ -135,4 +137,4 @@ private static Reference MakePrivateReference(Engine engine, JsValue baseValue, var privateName = privEnv!.ResolvePrivateIdentifier(privateIdentifier.ToString()); return engine._referencePool.Rent(baseValue, privateName!, strict: true, thisValue: null); } -} \ No newline at end of file +} diff --git a/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs index b35fedbbd..7cb696903 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs @@ -122,13 +122,16 @@ private JsValue UpdateNonIdentifier(EvaluationContext context) private JsValue? UpdateIdentifier(EvaluationContext context) { var name = _leftIdentifier!.Identifier; + var strict = StrictModeScope.IsStrictModeCode; + if (JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue( context.Engine.ExecutionContext.LexicalEnvironment, name, + strict, out var environmentRecord, out var value)) { - if (_evalOrArguments && StrictModeScope.IsStrictModeCode) + if (_evalOrArguments && strict) { ExceptionHelper.ThrowSyntaxError(context.Engine.Realm); } @@ -163,7 +166,7 @@ private JsValue UpdateNonIdentifier(EvaluationContext context) } } - environmentRecord.SetMutableBinding(name.Key, newValue!, StrictModeScope.IsStrictModeCode); + environmentRecord.SetMutableBinding(name.Key, newValue!, strict); if (_prefix) { return newValue; @@ -179,4 +182,4 @@ private JsValue UpdateNonIdentifier(EvaluationContext context) return null; } -} \ No newline at end of file +}