aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/bindings/napi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/bindings/napi.cpp')
-rw-r--r--src/javascript/jsc/bindings/napi.cpp142
1 files changed, 118 insertions, 24 deletions
diff --git a/src/javascript/jsc/bindings/napi.cpp b/src/javascript/jsc/bindings/napi.cpp
index 9a8a03405..3335cde9e 100644
--- a/src/javascript/jsc/bindings/napi.cpp
+++ b/src/javascript/jsc/bindings/napi.cpp
@@ -55,13 +55,12 @@ namespace Napi {
JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSObject* object, JSC::JSGlobalObject* globalObject)
{
-
+ JSC::gcProtect(object);
JSC::JSArray* exportKeys = ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include, std::nullopt);
- auto symbol = vm.symbolRegistry().symbolForKey("__BunTemporaryGlobal"_s);
- JSC::Identifier ident = JSC::Identifier::fromUid(symbol);
+ JSC::Identifier ident = JSC::Identifier::fromString(vm, "__BunTemporaryGlobal"_s);
WTF::StringBuilder sourceCodeBuilder = WTF::StringBuilder();
// TODO: handle symbol collision
- sourceCodeBuilder.append("var $$TempSymbol = Symbol.for('__BunTemporaryGlobal'), $$NativeModule = globalThis[$$TempSymbol]; globalThis[$$TempSymbol] = null;\n if (!$$NativeModule) { throw new Error('Assertion failure: Native module not found'); }\n\n"_s);
+ sourceCodeBuilder.append("\nvar $$NativeModule = globalThis['__BunTemporaryGlobal']; console.log($$NativeModule); globalThis['__BunTemporaryGlobal'] = null;\n if (!$$NativeModule) { throw new Error('Assertion failure: Native module not found'); }\n\n"_s);
for (unsigned i = 0; i < exportKeys->length(); i++) {
auto key = exportKeys->getIndexQuickly(i);
@@ -207,17 +206,32 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
}
WTF::String nameStr;
if (property.utf8name != nullptr) {
- nameStr = WTF::String::fromUTF8(property.utf8name);
+ nameStr = WTF::String::fromUTF8(property.utf8name).isolatedCopy();
} else if (property.name) {
- nameStr = toJS(property.name).toWTFString(globalObject);
+ nameStr = toJS(property.name).toWTFString(globalObject).isolatedCopy();
}
auto propertyName = JSC::PropertyName(JSC::Identifier::fromString(vm, nameStr));
if (property.method) {
- auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, nameStr, reinterpret_cast<Zig::FFIFunction>(property.method));
- function->dataPtr = dataPtr;
- JSC::JSValue value = JSC::JSValue(function);
+ JSC::JSValue value;
+ auto method = reinterpret_cast<Zig::FFIFunction>(property.method);
+ if (!dataPtr) {
+ JSC::JSNativeStdFunction* func = JSC::JSNativeStdFunction::create(
+ globalObject->vm(), globalObject, 1, String(), [method](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
+ JSC::MarkedArgumentBuffer values;
+ values.append(callFrame->thisValue());
+ for (int i = 0; i < callFrame->argumentCount(); i++) {
+ values.append(callFrame->argument(i));
+ }
+ return method(globalObject, callFrame);
+ });
+ value = JSC::JSValue(func);
+ } else {
+ auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, nameStr, method);
+ function->dataPtr = dataPtr;
+ value = JSC::JSValue(function);
+ }
to->putDirect(vm, propertyName, value, getPropertyAttributes(property) | JSC::PropertyAttribute::Function);
return;
@@ -233,6 +247,8 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
if (getterProperty) {
JSC::JSNativeStdFunction* getterFunction = JSC::JSNativeStdFunction::create(
globalObject->vm(), globalObject, 0, String(), [getterProperty](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
+ JSC::MarkedArgumentBufferWithSize values;
+ values.append(callFrame->thisValue());
return getterProperty(globalObject, callFrame);
});
getter = getterFunction;
@@ -247,8 +263,10 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
if (setterProperty) {
JSC::JSNativeStdFunction* setterFunction = JSC::JSNativeStdFunction::create(
globalObject->vm(), globalObject, 1, String(), [setterProperty](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
- setterProperty(globalObject, callFrame);
- return JSC::JSValue::encode(JSC::jsBoolean(true));
+ JSC::MarkedArgumentBufferWithSize values;
+ values.append(callFrame->thisValue());
+ values.append(callFrame->uncheckedArgument(0));
+ return setterProperty(globalObject, callFrame);
});
setter = setterFunction;
} else {
@@ -500,9 +518,9 @@ extern "C" napi_status napi_wrap(napi_env env,
extern "C" napi_status napi_unwrap(napi_env env, napi_value js_object,
void** result)
{
- // if (!toJS(js_object).isObject()) {
- // return NAPI_OBJECT_EXPECTED;
- // }
+ if (!toJS(js_object).isObject()) {
+ return NAPI_OBJECT_EXPECTED;
+ }
auto* globalObject = toJS(env);
auto& vm = globalObject->vm();
auto* object = JSC::jsDynamicCast<NapiPrototype*>(toJS(js_object));
@@ -521,12 +539,27 @@ extern "C" napi_status napi_create_function(napi_env env, const char* utf8name,
{
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
- auto name = WTF::String::fromUTF8(utf8name, length);
+ auto name = WTF::String::fromUTF8(utf8name, length == NAPI_AUTO_LENGTH ? strlen(utf8name) : length).isolatedCopy();
+ auto method = reinterpret_cast<Zig::FFIFunction>(cb);
+ if (data) {
+ auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, name, method);
+ function->dataPtr = data;
+ *result = toNapi(JSC::JSValue(function));
+ } else {
+ JSC::JSNativeStdFunction* func = JSC::JSNativeStdFunction::create(
+ globalObject->vm(), globalObject, 1, String(), [method](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
+ JSC::MarkedArgumentBuffer values;
+ values.append(callFrame->thisValue());
+ for (int i = 0; i < callFrame->argumentCount(); i++) {
+ values.append(callFrame->argument(i));
+ }
+ return method(globalObject, callFrame);
+ });
+ *result = toNapi(JSC::JSValue(func));
+ }
+
// std::cout << "napi_create_function: " << utf8name << std::endl;
- auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, name, reinterpret_cast<Zig::FFIFunction>(cb));
- function->dataPtr = data;
- JSC::JSValue functionValue = JSC::JSValue(function);
- *reinterpret_cast<JSC::EncodedJSValue*>(result) = JSC::JSValue::encode(functionValue);
+
return napi_ok;
}
@@ -559,8 +592,9 @@ extern "C" napi_status napi_get_cb_info(
}
}
+ JSC::JSValue thisValue = callFrame->thisValue();
+
if (this_arg != nullptr) {
- JSC::JSValue thisValue = callFrame->thisValue();
*this_arg = toNapi(thisValue);
}
@@ -568,8 +602,14 @@ extern "C" napi_status napi_get_cb_info(
JSC::JSValue callee = JSC::JSValue(callFrame->jsCallee());
if (Zig::JSFFIFunction* ffiFunction = JSC::jsDynamicCast<Zig::JSFFIFunction*>(callee)) {
*data = reinterpret_cast<void*>(ffiFunction->dataPtr);
- } else if (NapiPrototype* proto = JSC::jsDynamicCast<NapiPrototype*>(callee)) {
+ } else if (auto* proto = JSC::jsDynamicCast<NapiPrototype*>(callee)) {
*data = proto->napiRef ? proto->napiRef->data : nullptr;
+ } else if (auto* proto = JSC::jsDynamicCast<NapiClass*>(callee)) {
+ *data = proto->dataPtr;
+ } else if (auto* proto = JSC::jsDynamicCast<NapiPrototype*>(thisValue)) {
+ *data = proto->napiRef ? proto->napiRef->data : nullptr;
+ } else if (auto* proto = JSC::jsDynamicCast<NapiClass*>(thisValue)) {
+ *data = proto->dataPtr;
} else {
*data = nullptr;
}
@@ -595,6 +635,8 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
void* inheritedDataPtr = nullptr;
if (NapiPrototype* proto = jsDynamicCast<NapiPrototype*>(objectValue)) {
inheritedDataPtr = proto->napiRef ? proto->napiRef->data : nullptr;
+ } else if (NapiClass* proto = jsDynamicCast<NapiClass*>(objectValue)) {
+ inheritedDataPtr = proto->dataPtr;
}
for (size_t i = 0; i < property_count; i++) {
@@ -980,6 +1022,55 @@ static JSC_DEFINE_HOST_FUNCTION(NapiClass_ConstructorFunction,
callFrame->setThisValue(prototype->subclass(newTarget));
napi->constructor()(globalObject, callFrame);
+ size_t count = callFrame->argumentCount();
+
+ switch (count) {
+ case 0: {
+ break;
+ }
+ case 1: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ break;
+ }
+ case 2: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ JSC::ensureStillAliveHere(callFrame->argument(1));
+ break;
+ }
+ case 3: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ JSC::ensureStillAliveHere(callFrame->argument(1));
+ JSC::ensureStillAliveHere(callFrame->argument(2));
+ break;
+ }
+ case 4: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ JSC::ensureStillAliveHere(callFrame->argument(1));
+ JSC::ensureStillAliveHere(callFrame->argument(2));
+ JSC::ensureStillAliveHere(callFrame->argument(3));
+ break;
+ }
+ case 5: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ JSC::ensureStillAliveHere(callFrame->argument(1));
+ JSC::ensureStillAliveHere(callFrame->argument(2));
+ JSC::ensureStillAliveHere(callFrame->argument(3));
+ JSC::ensureStillAliveHere(callFrame->argument(4));
+ break;
+ }
+ default: {
+ JSC::ensureStillAliveHere(callFrame->argument(0));
+ JSC::ensureStillAliveHere(callFrame->argument(1));
+ JSC::ensureStillAliveHere(callFrame->argument(2));
+ JSC::ensureStillAliveHere(callFrame->argument(3));
+ JSC::ensureStillAliveHere(callFrame->argument(4));
+ JSC::ensureStillAliveHere(callFrame->argument(5));
+ for (int i = 6; i < count; i++) {
+ JSC::ensureStillAliveHere(callFrame->argument(i));
+ }
+ break;
+ }
+ }
RETURN_IF_EXCEPTION(scope, {});
RELEASE_AND_RETURN(scope, JSValue::encode(callFrame->thisValue()));
@@ -992,7 +1083,7 @@ NapiClass* NapiClass::create(VM& vm, Zig::GlobalObject* globalObject, const char
size_t property_count,
const napi_property_descriptor* properties)
{
- WTF::String name = WTF::String::fromUTF8(utf8name, length);
+ WTF::String name = WTF::String::fromUTF8(utf8name, length).isolatedCopy();
NativeExecutable* executable = vm.getHostFunction(NapiClass_ConstructorFunction, NapiClass_ConstructorFunction, name);
Structure* structure = globalObject->NapiClassStructure();
@@ -1098,8 +1189,11 @@ extern "C" napi_status napi_define_class(napi_env env,
{
Zig::GlobalObject* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
-
- NapiClass* napiClass = NapiClass::create(vm, globalObject, utf8name, length, constructor, data, property_count, properties);
+ size_t len = length;
+ if (len == NAPI_AUTO_LENGTH) {
+ len = strlen(utf8name);
+ }
+ NapiClass* napiClass = NapiClass::create(vm, globalObject, utf8name, len, constructor, data, property_count, properties);
JSC::JSValue value = JSC::JSValue(napiClass);
if (data != nullptr) {
napiClass->dataPtr = data;