…erto
Ataca a RAIZ que apareceu quatro vezes: "um i64 é um número". Aqui ela vivia na
camada de invocação de função, e é o que ainda travava `arr[Symbol.iterator]()`.
Três defeitos na mesma cadeia, todos corrigidos na declaração e não na borda:
1. `invoke_legacy_fn` (funcops.rs) boxava TODO retorno i64 como número
(`from_i32`/`from_f64`). Uma fn nativa que devolve um HANDLE de runtime —
`Array.prototype[Symbol.iterator]`, que devolve um iterador — tinha o handle
silenciosamente convertido em número: o caller lia `typeof === "number"` e
nenhum método funcionava.
Note que a direção de ENTRADA nunca teve esse bug: `word_to_raw_i64` já
reconhece uma word de heap e a cruza como handle real. Faltava a contraparte
de saída. `FunctionData.return_kind` ganha o valor `5` = HANDLE, boxado pela
autoridade única de retorno-de-handle (`__rtsadp_box_handle_auto`, que
inspeciona o `Entry` e escolhe a tag) em vez de adivinhado no invoker. `0`
(i64) continua ambíguo por definição — por isso a declaração é necessária.
2. `this` era passado DUAS vezes. `FUNCTION_CALL` já prepende `effective_this`
para um callee `has_this_param` (`function/ops.rs`, `all_args.insert(0, ..)`),
mas o invoker passava `0` como receiver E colocava o `this` nos slots
posicionais — então o callee recebia `this = 0` e cada argumento real
deslocado uma posição. `values_iter` recebia 0 e devolvia um iterador VAZIO.
Agora o `this` viaja pelo canal de receiver do `FUNCTION_CALL`.
3. `__rtsadp_idx_call` fazia `ToString` de uma chave SYMBOL → "[object Object]",
que errava toda linha de row e virava a TypeError sem sentido
"[object Object] is not a function". Ganha a branch de symbol que
`__rtsadp_dyn_idx_get` já tinha: resolve a propriedade e INVOCA.
Resultado: `tests/cross-runtime/object-meta/368_iterator_protocol.ts` (#2024),
que antes TRAVAVA (a `zip` fazia `a[Symbol.iterator]()`, o resultado não avançava
e o `while(true)` nunca terminava), agora roda inteira e é byte-idêntica ao Node.
Testes: `claude-iterador-nativo-next.test.ts` (19 → 23) ganha os casos de
`arr[Symbol.iterator]()` — typeof, `.next()`, avanço de cursor, spread. Fixture
cross-runtime ampliada, byte-idêntica a Node E Bun.
Suite: 2754/2755. A única falha — "window é o MESMO objeto entre scripts do
documento" — é PRÉ-EXISTENTE, verificada na main. O fix do `this` é amplo (toca
todo callee legado com `has_this_param`) e por isso a suite completa é a
validação que importa: nada regrediu.
PERMANECE, e é o mesmo eixo estático de sempre: consumir parcialmente com
`.next()` e depois espalhar/iterar reinicia do zero — o front prova "é array" e
emite index-walk a partir de 0, sem consultar o cursor. Registrado na #2042.
Closes #2024
Refs #2042, #2038
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017k43FcCXn8a1zqWfDmJAWr
A raiz, atacada de frente
A mesma causa apareceu quatro vezes nesta campanha: "um i64 é um número". Os três fixes anteriores a trataram na borda (#2043, #2045, #2046). Aqui ela é corrigida onde nasce — na camada de invocação de função —, e é o que ainda travava
arr[Symbol.iterator]().Três defeitos na mesma cadeia
1. O retorno de fn nativa era sempre número
invoke_legacy_fnboxava todo retorno i64 como número:Uma fn nativa que devolve um handle —
Array.prototype[Symbol.iterator], que devolve um iterador — tinha o handle convertido em número: o caller liatypeof === "number"e nenhum método funcionava.A direção de entrada nunca teve esse bug —
word_to_raw_i64já reconhece uma word de heap e a cruza como handle real. Faltava a contraparte de saída.FunctionData.return_kindganha5= HANDLE, boxado pela autoridade única de retorno-de-handle (__rtsadp_box_handle_auto, que inspeciona oEntrye escolhe a tag) em vez de adivinhado.0(i64) continua ambíguo por definição — por isso a declaração é necessária, e não mais um caso especial.2.
thisera passado duas vezesFUNCTION_CALLjá prependeeffective_thispara um calleehas_this_param(all_args.insert(0, ..)), mas o invoker passava0como receiver e colocava othisnos slots posicionais. O callee recebiathis = 0e cada argumento real deslocado uma posição —values_iterrecebia 0 e devolvia um iterador vazio.3. Symbol key virava
"[object Object]"__rtsadp_idx_callfaziaToStringda chave symbol, errava toda linha de row, e produzia a TypeError sem sentido"[object Object] is not a function". Ganha a branch de symbol que__rtsadp_dyn_idx_getjá tinha.Resultado
368_iterator_protocol(#2024) passa byte-idêntica ao Node. Antes ela travava: azipfaziaa[Symbol.iterator](), o resultado não avançava, e owhile(true)nunca terminava.Validação
claude-iterador-nativo-next.test.ts— 19 → 23: novos casos dearr[Symbol.iterator]()(typeof,.next(), avanço de cursor, spread).O fix do
thisé amplo (toca todo callee legado comhas_this_param), por isso a suite completa é a validação que importa: nada regrediu.O que permanece
Consumir parcialmente com
.next()e depois espalhar/iterar reinicia do zero — o front prova "é array" e emite index-walk a partir de 0, sem consultar o cursor. É o mesmo eixo estático de sempre; registrado na #2042.Closes #2024
Refs #2042, #2038
🤖 Generated with Claude Code