import.meta in any non-builtin module fails with "uncaught exception: undefined" (module_metadata_hook returns false without an exception)

未关闭 适合新手
#355 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
c, javascript, wasm
领域
backend

调研方向

从 runtime/script_loader.cpp 中的 module_metadata_hook 开始,issue 指出对普通模块返回 false 是原因。检查模块加载测试,并添加一个在用户模块中计算 typeof import.meta 的回归用例。普通模块求值成功且回归用例通过时,issue 即完成;builtin 模块应保留其 import.meta.builtin 行为。

由索引模型根据 Issue 内容生成。

描述

Summary

Evaluating import.meta in a user module aborts the module with an uncatchable error, because the module metadata
hook returns false without setting an exception. try/catch around it does not help. In a ComponentizeJS component
the exported function traps.

Environment

  • StarlingMonkey v0.4.0 release starling.wasm, wasmtime 50.0.1, module mode (wasmtime run -S http --dir . starling.wasm main.js).
  • runtime/script_loader.cpp is unchanged on main (54b3329b).
  • Also seen with @bytecodealliance/componentize-js 0.23.0.
  • Checked on 2026-11-03. Reference: SpiderMonkey jsshell 147.0.4 (the SpiderMonkey version StarlingMonkey v0.4.0 embeds), js -m.

Reproduction

// main.js
console.log(typeof import.meta);
console.log(import.meta.url);

StarlingMonkey:

Exception while evaluating top-level script
uncaught exception: undefined
Additionally, some promises were rejected, but the rejection never handled:
Promise rejected but never handled: (void 0)

jsshell prints object and the module's location. The same failure happens in an imported (non-entry) module, and
when the access is wrapped in try { … } catch (e) { … }: neither the catch block nor the code after it runs.

ComponentizeJS 0.23.0:

export function run() {
  try { return typeof import.meta + " " + import.meta.url; } catch (e) { return "threw " + e; }
}

wasmtime run -S http --invoke 'run()' component.wasm prints uncaught exception: undefined and the instance traps
(wasm 'unreachable' instruction executed).

test262: language/expressions/import.meta/same-object-returned.js and import-meta-is-an-ordinary-object.js fail
the same way.

Expected

import.meta is an ordinary object and evaluating it does not throw
(spec). The host hooks
HostGetImportMetaProperties and
HostFinalizeImportMeta return a List / nothing, not a
completion, so they cannot fail. Hosts may add properties such as url.

Cause

runtime/script_loader.cpp:

bool module_metadata_hook(JSContext *cx, HandleValue ref_priv, HandleObject meta_obj) {
  ...
  RootedValue builtin_val(cx);
  if (!MapGet(cx, builtinModules, parent_id_val, &builtin_val)) {
    return false;
  }
  if (builtin_val.isUndefined()) {
    return false;          // every non-builtin module ends up here, with no pending exception
  }
  JS_SetProperty(cx, meta_obj, "builtin", builtin_val);
  return true;
}

The hook exists to give builtin modules import.meta.builtin. For ordinary modules it returns false, which
SpiderMonkey treats as an uncatchable error. (The !parent_id_val.isString() branch has the same problem.)

Suggested fix

  if (builtin_val.isUndefined()) {
    return true;   // ordinary module: nothing to add
  }

Optionally also set import.meta.url (as a file:// URL built from the resolved module path) and
import.meta.resolve, as other hosts do. A regression test is console.log(typeof import.meta) in a user module.

主要语言
C
星标
297
派生
64
平均合并
2 天 2 小时
30 天内合并 PR
19

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

bytecodealliance/StarlingMonkey 的其他 Issue

查看 bytecodealliance/StarlingMonkey 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。