Skip to content

fix: replace panics with proper error handling in module env and dyna…#5051

Open
tkshsbcue wants to merge 2 commits intoboa-dev:mainfrom
tkshsbcue:fix/replace-panics-with-errors
Open

fix: replace panics with proper error handling in module env and dyna…#5051
tkshsbcue wants to merge 2 commits intoboa-dev:mainfrom
tkshsbcue:fix/replace-panics-with-errors

Conversation

@tkshsbcue
Copy link
Contributor

Description

This PR replaces two panic!() calls with proper JsNativeError::TypeError returns, preventing the engine from crashing on edge cases that should produce JavaScript errors instead.

1. Dynamic import with synthetic module referrer

In load_dyn_import, if a synthetic module is unexpectedly used as a referrer for a dynamic import() call, the engine panicked. This now returns a TypeError, allowing the promise to reject gracefully instead of crashing the process.

File: vm/opcode/call/mod.rs:381

2. Module environment indirect binding mutation

In ModuleEnvironment::set, attempting to set an indirect binding (a re-export from another module) caused a panic!(). Per the ECMAScript spec, module export bindings are immutable from the importing side. This now returns a TypeError.

File: environments/runtime/declarative/module.rs:108

This required propagating JsResult<()> through the environment set() call chain:

  • LexicalEnvironment::set, GlobalEnvironment::set, FunctionEnvironment::set (trivially return Ok(()))
  • DeclarativeEnvironmentKind::set, DeclarativeEnvironment::set
  • EnvironmentStack::put_lexical_value, EnvironmentStack::put_value_if_uninitialized
  • All callers updated to propagate errors with ?

Changes

File Change
vm/opcode/call/mod.rs panic!() -> Err(JsNativeError::typ()) in load_dyn_import
environments/runtime/declarative/module.rs panic!() -> Err(JsNativeError::typ()) in set()
environments/runtime/declarative/lexical.rs set() returns JsResult<()>
environments/runtime/declarative/global.rs set() returns JsResult<()>
environments/runtime/declarative/function.rs set() returns JsResult<()>
environments/runtime/declarative/mod.rs Propagate JsResult through set()
environments/runtime/mod.rs put_lexical_value and put_value_if_uninitialized return JsResult<()>
vm/opcode/define/mod.rs DefVar and PutLexicalValue operations return JsResult<()>
module/source.rs Propagate ? on put_lexical_value calls
module/synthetic.rs Propagate ? on set() and put_lexical_value calls
builtins/function/mod.rs Propagate ? on put_lexical_value calls
builtins/function/arguments.rs Handle set() result for mapped arguments

Test plan

  • cargo check -- clean, no warnings
  • cargo clippy -- no warnings
  • cargo test -p boa_engine --lib -- all 958 tests pass
  • CI should confirm no regressions

…mic import

- Replace panic!() in load_dyn_import with JsNativeError::TypeError
  when a synthetic module is unexpectedly used as a referrer
- Replace panic!() in ModuleEnvironment::set with JsNativeError::TypeError
  when attempting to modify an indirect binding reference
- Propagate JsResult through the environment set() call chain:
  DeclarativeEnvironment, put_lexical_value, put_value_if_uninitialized
- Update all callers to handle the new Result return type
@tkshsbcue tkshsbcue requested a review from a team as a code owner March 14, 2026 03:25
@github-actions
Copy link

github-actions bot commented Mar 14, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,963 52,963 0
Passed 49,935 49,713 -222
Ignored 2,207 2,262 +55
Failed 821 988 +167
Panics 0 0 0
Conformance 94.28% 93.86% -0.42%
Fixed tests (2):
test/built-ins/RegExp/regexp-modifiers/remove-ignoreCase-affects-slash-upper-b.js (previously Failed)
test/built-ins/RegExp/regexp-modifiers/remove-ignoreCase-affects-slash-lower-b.js (previously Failed)
Broken tests (175):
test/intl402/supportedLocalesOf-test-option-localeMatcher.js (previously Passed)
test/intl402/supportedLocalesOf-returned-array-elements-are-not-frozen.js (previously Passed)
test/intl402/supportedLocalesOf-unicode-extensions-ignored.js (previously Passed)
test/intl402/supportedLocalesOf-default-locale-and-zxx-locale.js (previously Passed)
test/intl402/supportedLocalesOf-taint-Array-2.js (previously Passed)
test/intl402/supportedLocalesOf-empty-and-undefined.js (previously Passed)
test/intl402/default-locale-is-supported.js (previously Passed)
test/intl402/supportedLocalesOf-locales-arg-empty-array.js (previously Passed)
test/intl402/supportedLocalesOf-consistent-with-resolvedOptions.js (previously Passed)
test/intl402/supportedLocalesOf-taint-Array.js (previously Passed)
test/intl402/supportedLocalesOf-locales-arg-coered-to-object.js (previously Passed)
test/intl402/supportedLocalesOf-duplicate-elements-removed.js (previously Passed)
test/intl402/language-tags-canonicalized.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/length.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/basic.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/builtin.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/name.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lisu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Garay.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Extender.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Casemapped.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/XID_Continue.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tangut.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kaithi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Bengali.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tai_Yo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Decimal_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Beria_Erfe.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Common.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Uppercase.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Cyrillic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Lowercase.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Elbasan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kawi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Latin.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Permic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Khitan_Small_Script.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Case_Ignorable.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_NFKC_Casefolded.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Avestan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Carian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Titlecased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Meroitic_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Modifier_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Mongolian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Common.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kirat_Rai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sidetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gunjala_Gondi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Myanmar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Grapheme_Extend.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tulu_Tigalari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Extended_Pictographic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Cased_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Lowercase_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Latin.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gothic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tolong_Siki.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gurung_Khema.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kawi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Balinese.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Bopomofo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/ID_Start.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Thai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Myanmar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Georgian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Assigned.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Math.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Math_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Glagolitic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Turkic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Emoji_Presentation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Samaritan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Todhri.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Nonspacing_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Uppercased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Ideographic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sunuwar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Cased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Katakana.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Casefolded.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tibetan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Dash_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Cherokee.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Ethiopic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Beria_Erfe.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Lowercased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Letter_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Telugu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Greek.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Adlam.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Han.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Mahajani.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Egyptian_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Ol_Onal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lycian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tolong_Siki.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sharada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tifinagh.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Garay.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lydian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Phags_Pa.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Egyptian_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Shavian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Telugu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/ID_Continue.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Runic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tai_Yo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Newa.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kirat_Rai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Han.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Bidi_Mirrored.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Arabic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Dash.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kannada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Ol_Onal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Coptic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kannada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Todhri.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Nandinagari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Alphabetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Cyrillic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sunuwar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Syriac.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Diacritic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Sentence_Terminal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Osage.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Gurung_Khema.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tirhuta.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tangut.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Hungarian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tulu_Tigalari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sharada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Terminal_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Inherited.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Khitan_Small_Script.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Grapheme_Base.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Unassigned.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Toto.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Armenian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tai_Le.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Devanagari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Uppercase_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Arabic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/XID_Start.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Duployan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Spacing_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sidetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Hebrew.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Caucasian_Albanian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Balinese.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Currency_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Inherited.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Unified_Ideograph.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence.js (previously Passed)
test/built-ins/RegExp/regexp-modifiers/add-ignoreCase-affects-slash-upper-w.js (previously Passed)
test/built-ins/RegExp/regexp-modifiers/add-ignoreCase-affects-slash-lower-w.js (previously Passed)
test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js (previously Passed)
test/staging/sm/RegExp/unicode-ignoreCase.js (previously Passed)
test/staging/sm/RegExp/unicode-ignoreCase-word-boundary.js (previously Passed)

Tested main commit: 40f99905eefb4ac0542e4b7686425ffeb17ff09a
Tested PR commit: 3bf6c1a051d9000924c1bfec8272a88940a5c1a7
Compare commits: 40f9990...3bf6c1a

@tkshsbcue
Copy link
Contributor Author

@jedel1043 i hope you can review my PR

Thanks!

@jedel1043
Copy link
Member

jedel1043 commented Mar 14, 2026

We still want to signal some kind of panic, because if we're trying to get an indirect binding by index, it means that our bytecompiler or our VM has a bug in the bindings resolution code.

I would suggest changing the error in set to be a PanicError.

ModuleEnvironment::set on an indirect binding indicates an internal
bug in the bytecompiler or VM binding resolution, not a user-facing
error. Use PanicError to signal this correctly.
@tkshsbcue
Copy link
Contributor Author

hey @jedel1043 i have taken than account and fixed that

@jedel1043
Copy link
Member

Need to rebase

@jedel1043 jedel1043 added A-Technical Debt Changes related to technical debt C-VM Issues and PRs related to the Boa Virtual Machine. labels Mar 16, 2026
@jedel1043 jedel1043 added this to the v1.0.0 milestone Mar 16, 2026
@jedel1043 jedel1043 added the Waiting On Author Waiting on PR changes from the author label Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Technical Debt Changes related to technical debt C-VM Issues and PRs related to the Boa Virtual Machine. Waiting On Author Waiting on PR changes from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants