Skip to content

Commit

Permalink
[napi] Support defining properties with symbol as names
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner committed Jan 23, 2023
1 parent aa45680 commit 4570ff7
Showing 1 changed file with 36 additions and 12 deletions.
48 changes: 36 additions & 12 deletions src/bun.js/bindings/napi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
// }
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 4570ff7

Please sign in to comment.