aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-01-23 15:08:45 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-01-23 15:09:23 -0800
commit4570ff77807a334f7bcd23e4b69b758d365b82a0 (patch)
treef06f28ce336b32c989c3f79b6a03ff872a8ca860
parentaa456805ddc9fd44152d73888ecb8733b60f34b9 (diff)
downloadbun-4570ff77807a334f7bcd23e4b69b758d365b82a0.tar.gz
bun-4570ff77807a334f7bcd23e4b69b758d365b82a0.tar.zst
bun-4570ff77807a334f7bcd23e4b69b758d365b82a0.zip
[napi] Support defining properties with symbol as names
-rw-r--r--src/bun.js/bindings/napi.cpp48
1 files changed, 36 insertions, 12 deletions
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp
index db70ad1ca..d42ee9da1 100644
--- a/src/bun.js/bindings/napi.cpp
+++ b/src/bun.js/bindings/napi.cpp
@@ -204,21 +204,35 @@ static uint32_t getPropertyAttributes(napi_property_descriptor prop)
return result;
}
-static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance)
+static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance, JSC::ThrowScope& scope)
{
JSC::VM& vm = globalObject->vm();
void* dataPtr = property.data;
if (!dataPtr) {
dataPtr = inheritedDataPtr;
}
- WTF::String nameStr;
- if (property.utf8name != nullptr) {
- nameStr = WTF::String::fromUTF8(property.utf8name).isolatedCopy();
- } else if (property.name) {
- nameStr = toJS(property.name).toWTFString(globalObject).isolatedCopy();
- }
- auto propertyName = JSC::PropertyName(JSC::Identifier::fromString(vm, nameStr));
+ auto getPropertyName = [&]() -> JSC::Identifier {
+ if (property.utf8name != nullptr) {
+ size_t len = strlen(property.utf8name);
+ if (len > 0) {
+ return JSC::Identifier::fromString(vm, WTF::String::fromUTF8(property.utf8name, len).isolatedCopy());
+ }
+ }
+
+ if (!property.name) {
+ throwVMError(globalObject, scope, JSC::createTypeError(globalObject, "Property name is required"_s));
+ return JSC::Identifier();
+ }
+
+ JSValue nameValue = toJS(property.name);
+ return nameValue.toPropertyKey(globalObject);
+ };
+
+ JSC::Identifier propertyName = getPropertyName();
+ if (propertyName.isEmpty()) {
+ return;
+ }
if (property.method) {
JSC::JSValue value;
@@ -235,7 +249,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
// });
// value = JSC::JSValue(func);
// } else {
- auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, nameStr, method);
+ auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, propertyName.isSymbol() ? String() : propertyName.string(), method);
function->dataPtr = dataPtr;
value = JSC::JSValue(function);
// }
@@ -727,6 +741,7 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
JSC::JSValue objectValue = toJS(object);
JSC::JSObject* objectObject = objectValue.getObject();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
if (!objectObject) {
return NAPI_OBJECT_EXPECTED;
@@ -740,9 +755,13 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
}
for (size_t i = 0; i < property_count; i++) {
- defineNapiProperty(globalObject, objectObject, inheritedDataPtr, properties[i], true);
+ defineNapiProperty(globalObject, objectObject, inheritedDataPtr, properties[i], true, throwScope);
+
+ RETURN_IF_EXCEPTION(throwScope, napi_generic_failure);
}
+ throwScope.release();
+
return napi_ok;
}
@@ -1263,14 +1282,19 @@ void NapiClass::finishCreation(VM& vm, NativeExecutable* executable, unsigned le
NapiPrototype* prototype = NapiPrototype::create(vm, globalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
for (size_t i = 0; i < property_count; i++) {
const napi_property_descriptor& property = properties[i];
if (property.attributes & napi_static) {
- defineNapiProperty(globalObject, this, nullptr, property, true);
+ defineNapiProperty(globalObject, this, nullptr, property, true, throwScope);
} else {
- defineNapiProperty(globalObject, prototype, nullptr, property, false);
+ defineNapiProperty(globalObject, prototype, nullptr, property, false, throwScope);
}
+
+ if (throwScope.exception())
+ break;
}
this->putDirect(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | 0);