Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

napi_get_property_names: throws on JavaScriptCore; inconsistent enumerability/prototype semantics on Chakra and QuickJS

已关闭
#216 0 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 1 天内回复

@bkaradzic-microsoft 已经在做这个了。

开始于 2026年7月30日。

评估

这个 Issue 还没有评估数据。

描述

bug

napi_get_property_names behaves differently on all three non-V8 backends, and throws unconditionally on JavaScriptCore. Since Napi::Object::GetPropertyNames() is a direct wrapper, that method is unusable on JSC for every N-API caller — and JSC is the default engine on macOS and iOS.

Reference behaviour (V8)

js_native_api_v8.cc matches the Node-API specification: enumerable, string-keyed properties, including the prototype chain.

obj->GetPropertyNames(
    context,
    v8::KeyCollectionMode::kIncludePrototypes,
    static_cast<v8::PropertyFilter>(
        v8::PropertyFilter::ONLY_ENUMERABLE |
        v8::PropertyFilter::SKIP_SYMBOLS),
    v8::IndexFilter::kIncludeIndices,
    v8::KeyConversionMode::kConvertToString);

JavaScriptCore — throws

Core/Node-API/Source/js_native_api_javascriptcore.cc:

CHECK_NAPI(napi_get_named_property(env, object_ctor, "getOwnPropertyNames", &function));
CHECK_NAPI(napi_call_function(env, object_ctor, function, 0, nullptr, result));

The object parameter is never used. The call passes argc 0 / argv nullptr, so it evaluates Object.getOwnPropertyNames(undefined), which throws TypeError. Note there is also no CHECK_ARG(env, object).

Passing the object is necessary but not sufficient. Object.getOwnPropertyNames is own-only and includes non-enumerable properties, so it disagrees with V8 on both axes. A conforming JSC implementation needs enumerable properties across the prototype chain — the semantics of for...in filtered to string keys.

Chakra — own-only, includes non-enumerables

js_native_api_chakra.cc uses JsGetOwnPropertyNames, which is own-only and does not filter to enumerable properties. Wrong on both axes, though it does not throw.

QuickJS — own-only

js_native_api_quickjs.cc uses JS_GetOwnPropertyNames with JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY. Enumerability is correct; the prototype chain is missing.

Summary

backend enumerable-only includes prototype chain throws
V8 yes yes no
JavaScriptCore n/a n/a yes
Chakra no no no
QuickJS yes no no

Repro

const proto = { inherited: 1 };
const obj = Object.create(proto);
obj.own = 2;
Object.defineProperty(obj, "hidden", { value: 3, enumerable: false });
// napi_get_property_names(obj) should yield exactly ["own", "inherited"].

On JSC this throws instead of returning. On Chakra it yields ["own", "hidden"]. On QuickJS it yields ["own"].

Impact / workaround

Encountered in Babylon Native while enumerating a plain JS data object (BabylonJS/BabylonNative#1797). The workaround is to fetch Object.keys from the global and call it via napi_call_function, which behaves consistently across engines for plain data objects:

const auto objectCtor = env.Global().Get("Object").As<Napi::Object>();
const auto keys = objectCtor.Get("keys").As<Napi::Function>();

That is only equivalent for own-enumerable cases, so it is a local workaround rather than a fix.

主要语言
C++
星标
22
派生
23
平均合并
6 小时 17 分钟
30 天内合并 PR
4

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

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

BabylonJS/JsRuntimeHost 的其他 Issue

查看 BabylonJS/JsRuntimeHost 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

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