mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
182 lines
5.4 KiB
C++
182 lines
5.4 KiB
C++
#include <node.h>
|
|
|
|
#include <inttypes.h>
|
|
#include <iostream>
|
|
#include <napi.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#include <cassert>
|
|
|
|
napi_value fail(napi_env env, const char *msg) {
|
|
napi_value result;
|
|
napi_create_string_utf8(env, msg, NAPI_AUTO_LENGTH, &result);
|
|
return result;
|
|
}
|
|
|
|
napi_value fail_fmt(napi_env env, const char *fmt, ...) {
|
|
char buf[1024];
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
|
va_end(args);
|
|
return fail(env, buf);
|
|
}
|
|
|
|
napi_value ok(napi_env env) {
|
|
napi_value result;
|
|
napi_get_undefined(env, &result);
|
|
return result;
|
|
}
|
|
|
|
napi_value test_issue_7685(const Napi::CallbackInfo &info) {
|
|
Napi::Env env(info.Env());
|
|
Napi::HandleScope scope(env);
|
|
#define napi_assert(expr) \
|
|
{ \
|
|
if (!expr) { \
|
|
Napi::Error::New(env, #expr).ThrowAsJavaScriptException(); \
|
|
} \
|
|
}
|
|
napi_assert(info[0].IsNumber());
|
|
napi_assert(info[1].IsNumber());
|
|
napi_assert(info[2].IsNumber());
|
|
napi_assert(info[3].IsNumber());
|
|
napi_assert(info[4].IsNumber());
|
|
napi_assert(info[5].IsNumber());
|
|
napi_assert(info[6].IsNumber());
|
|
napi_assert(info[7].IsNumber());
|
|
return ok(env);
|
|
}
|
|
|
|
napi_threadsafe_function tsfn_11949;
|
|
napi_value tsfn_name_11949;
|
|
|
|
static void test_issue_11949_callback(napi_env env, napi_value js_callback,
|
|
void *context, void *data) {
|
|
if (data != nullptr) {
|
|
printf("data: %p\n", data);
|
|
} else {
|
|
printf("data: nullptr\n");
|
|
}
|
|
napi_unref_threadsafe_function(env, tsfn_11949);
|
|
}
|
|
|
|
static napi_value test_issue_11949(const Napi::CallbackInfo &info) {
|
|
Napi::Env env(info.Env());
|
|
Napi::HandleScope scope(env);
|
|
napi_status status;
|
|
status = napi_create_string_utf8(env, "TSFN", 4, &tsfn_name_11949);
|
|
assert(status == napi_ok);
|
|
status = napi_create_threadsafe_function(
|
|
env, NULL, NULL, tsfn_name_11949, 0, 1, NULL, NULL, NULL,
|
|
&test_issue_11949_callback, &tsfn_11949);
|
|
assert(status == napi_ok);
|
|
status =
|
|
napi_call_threadsafe_function(tsfn_11949, NULL, napi_tsfn_nonblocking);
|
|
assert(status == napi_ok);
|
|
napi_value result;
|
|
status = napi_get_undefined(env, &result);
|
|
assert(status == napi_ok);
|
|
return result;
|
|
}
|
|
|
|
static void callback_1(napi_env env, napi_value js_callback, void *context,
|
|
void *data) {}
|
|
|
|
napi_value test_napi_threadsafe_function_does_not_hang_after_finalize(
|
|
const Napi::CallbackInfo &info) {
|
|
|
|
Napi::Env env = info.Env();
|
|
napi_status status;
|
|
|
|
napi_value resource_name;
|
|
status = napi_create_string_utf8(env, "simple", 6, &resource_name);
|
|
assert(status == napi_ok);
|
|
|
|
napi_threadsafe_function cb;
|
|
status = napi_create_threadsafe_function(env, nullptr, nullptr, resource_name,
|
|
0, 1, nullptr, nullptr, nullptr,
|
|
&callback_1, &cb);
|
|
assert(status == napi_ok);
|
|
|
|
status = napi_release_threadsafe_function(cb, napi_tsfn_release);
|
|
assert(status == napi_ok);
|
|
|
|
printf("success!");
|
|
|
|
return ok(env);
|
|
}
|
|
|
|
napi_value
|
|
test_napi_get_value_string_utf8_with_buffer(const Napi::CallbackInfo &info) {
|
|
Napi::Env env = info.Env();
|
|
|
|
// get how many chars we need to copy
|
|
uint32_t _len;
|
|
if (napi_get_value_uint32(env, info[1], &_len) != napi_ok) {
|
|
return fail(env, "call to napi_get_value_uint32 failed");
|
|
}
|
|
size_t len = (size_t)_len;
|
|
|
|
if (len == 424242) {
|
|
len = NAPI_AUTO_LENGTH;
|
|
} else if (len > 29) {
|
|
return fail(env, "len > 29");
|
|
}
|
|
|
|
size_t copied;
|
|
const size_t BUF_SIZE = 30;
|
|
char buf[BUF_SIZE];
|
|
memset(buf, '*', BUF_SIZE);
|
|
buf[BUF_SIZE - 1] = '\0';
|
|
|
|
if (napi_get_value_string_utf8(env, info[0], buf, len, &copied) != napi_ok) {
|
|
return fail(env, "call to napi_get_value_string_utf8 failed");
|
|
}
|
|
|
|
std::cout << "Chars to copy: " << len << std::endl;
|
|
std::cout << "Copied chars: " << copied << std::endl;
|
|
std::cout << "Buffer: ";
|
|
for (size_t i = 0; i < BUF_SIZE; i++) {
|
|
std::cout << (int)buf[i] << ", ";
|
|
}
|
|
std::cout << std::endl;
|
|
std::cout << "Value str: " << buf << std::endl;
|
|
return ok(env);
|
|
}
|
|
|
|
Napi::Value RunCallback(const Napi::CallbackInfo &info) {
|
|
Napi::Env env = info.Env();
|
|
Napi::Function cb = info[0].As<Napi::Function>();
|
|
return cb.Call(env.Global(), {Napi::String::New(env, "hello world")});
|
|
}
|
|
|
|
Napi::Object Init2(Napi::Env env, Napi::Object exports) {
|
|
return Napi::Function::New(env, RunCallback);
|
|
}
|
|
|
|
Napi::Object InitAll(Napi::Env env, Napi::Object exports1) {
|
|
// check that these symbols are defined
|
|
auto *isolate = v8::Isolate::GetCurrent();
|
|
|
|
Napi::Object exports = Init2(env, exports1);
|
|
|
|
node::AddEnvironmentCleanupHook(isolate, [](void *) {}, isolate);
|
|
node::RemoveEnvironmentCleanupHook(isolate, [](void *) {}, isolate);
|
|
|
|
exports.Set("test_issue_7685", Napi::Function::New(env, test_issue_7685));
|
|
exports.Set("test_issue_11949", Napi::Function::New(env, test_issue_11949));
|
|
exports.Set(
|
|
"test_napi_get_value_string_utf8_with_buffer",
|
|
Napi::Function::New(env, test_napi_get_value_string_utf8_with_buffer));
|
|
exports.Set(
|
|
"test_napi_threadsafe_function_does_not_hang_after_finalize",
|
|
Napi::Function::New(
|
|
env, test_napi_threadsafe_function_does_not_hang_after_finalize));
|
|
|
|
return exports;
|
|
}
|
|
|
|
NODE_API_MODULE(napitests, InitAll)
|