From c6cacec5206aa7ee7181c1604f92ab8cedb89af6 Mon Sep 17 00:00:00 2001 From: Koji Ishimoto Date: Fri, 26 Jun 2026 00:18:18 +0900 Subject: [PATCH 1/2] fix(array): respect deletion of Array.prototype[Symbol.iterator] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `get_computed_property_impl` Array arm had a hard-coded synthesis block that returned a default array iterator for Symbol.iterator lookups after the prototype chain walk found nothing. This meant that `delete Array.prototype[Symbol.iterator]` had no effect: arrays remained iterable, so ArrayBindingPattern destructuring (§7.4.1 GetIterator) never threw the expected TypeError. The block was described as a fallback for "before setup_iterator_protocol is called", but setup_iterator_protocol writes symbol_properties[iterator_sym.id] on Array.prototype (builtins_iterator.mbt:60), so the prototype chain walk at lines 935-936 handles all normal cases and the synthesis block is unreachable in that path — it only fires in the delete case, which is the bug. The instance-level checks at lines 906-918 already cover own-property Symbol.iterator overrides (accessors and values), so removing the synthesis block does not regress any custom-iterator use case. Fixes 40 strict + 40 non-strict test262 failures (language/.../dstr/ary-init-iter-get-err-array-prototype across arrow-function, generators, class methods, function params, etc.) Co-Authored-By: Claude Sonnet 4.6 --- interpreter/runtime/property.mbt | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/interpreter/runtime/property.mbt b/interpreter/runtime/property.mbt index 76e91feb..385c798d 100644 --- a/interpreter/runtime/property.mbt +++ b/interpreter/runtime/property.mbt @@ -961,31 +961,6 @@ fn Interpreter::get_computed_property_impl( } _ => () } - // Handle Symbol.iterator default for arrays - let iterator_sym = well_known_symbols.iterator - if sym.id == iterator_sym.id { - let (override_getter, override_value) = get_array_iterator_override( - arr, - well_known_symbols~, - ) - match override_getter { - Some(getter) => return self.call_value(getter, obj, [], loc) - None => () - } - match override_value { - Some(v) => return v - None => () - } - // Return default array iterator - return make_method_func( - name="[Symbol.iterator]", - length=0, - realm_state=Some(realm_state), - fn(_this_val, _args) { - realm_state.make_array_iterator_value(arr) - }, - ) - } return Undefined } Map(map_data) => { From c1b97c1291925139629546a0d9342114e9554819 Mon Sep 17 00:00:00 2001 From: Koji Ishimoto Date: Fri, 26 Jun 2026 00:29:26 +0900 Subject: [PATCH 2/2] fix(array): continue symbol lookup through non-Object array prototype overrides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `get_array_prototype` can return `Array(...)`, `Proxy(...)`, or any other Value when the prototype was overridden via `Object.setPrototypeOf`. The previous `_ => ()` wildcard silently swallowed all these cases, causing `get_computed_property` to return `Undefined` even when Symbol.iterator was reachable through the prototype chain. Replace the wildcard with: - `Null | Undefined` → end of chain (same semantics as before) - any other Value → delegate to `self.get_computed_property`, which already dispatches through Array, Proxy, Map, Set, and Object arms This makes the following cases work correctly: - `Object.setPrototypeOf(a, []); a[Symbol.iterator]` - `Object.setPrototypeOf(a, new Proxy(Array.prototype, {})); for (x of a)` while preserving the fix from the parent commit: after a real `delete Array.prototype[Symbol.iterator]`, the prototype chain walk via the `Object(proto_data)` arm finds nothing, falls through to `Null | Undefined`, and returns Undefined as required by GetIterator §7.4.1. Co-Authored-By: Claude Sonnet 4.6 --- interpreter/runtime/property.mbt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interpreter/runtime/property.mbt b/interpreter/runtime/property.mbt index 385c798d..4b133c51 100644 --- a/interpreter/runtime/property.mbt +++ b/interpreter/runtime/property.mbt @@ -959,7 +959,9 @@ fn Interpreter::get_computed_property_impl( } } } - _ => () + Null | Undefined => () + proto_val => + return self.get_computed_property(proto_val, Symbol(sym), loc) } return Undefined }