mirror of
https://github.com/oven-sh/bun
synced 2026-02-05 00:18:53 +00:00
Compare commits
12 Commits
dylan/pyth
...
kai/more-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93e622e782 | ||
|
|
dac4c8623d | ||
|
|
12de2d58c2 | ||
|
|
4b97c78dff | ||
|
|
f92e2d5d37 | ||
|
|
890fb04a09 | ||
|
|
f99d1bce54 | ||
|
|
57a3f839e5 | ||
|
|
b98fe402be | ||
|
|
85499c8709 | ||
|
|
bfc423eeb9 | ||
|
|
9e9d137ca2 |
@@ -777,35 +777,22 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
target_compile_options(${bun} PUBLIC
|
||||
-Werror=return-type
|
||||
-Werror=return-stack-address
|
||||
-Werror=implicit-function-declaration
|
||||
-Werror=uninitialized
|
||||
-Werror=conditional-uninitialized
|
||||
-Werror=suspicious-memaccess
|
||||
-Werror=int-conversion
|
||||
-Werror=nonnull
|
||||
-Werror=move
|
||||
-Werror=sometimes-uninitialized
|
||||
-Werror=unused
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-function
|
||||
-Wno-nullability-completeness
|
||||
-Wno-unused-parameter
|
||||
-Wno-sign-compare
|
||||
-Werror
|
||||
)
|
||||
else()
|
||||
# Leave -Werror=unused off in release builds so we avoid errors from being used in ASSERT
|
||||
target_compile_options(${bun} PUBLIC ${LTO_FLAG}
|
||||
-Werror=return-type
|
||||
-Werror=return-stack-address
|
||||
-Werror=implicit-function-declaration
|
||||
-Werror=uninitialized
|
||||
-Werror=conditional-uninitialized
|
||||
-Werror=suspicious-memaccess
|
||||
-Werror=int-conversion
|
||||
-Werror=nonnull
|
||||
-Werror=move
|
||||
-Werror=sometimes-uninitialized
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-nullability-completeness
|
||||
-Wno-unused-parameter
|
||||
-Wno-sign-compare
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -73,6 +73,8 @@ const URL = @import("../../url.zig").URL;
|
||||
const VirtualMachine = JSC.VirtualMachine;
|
||||
const IOTask = JSC.IOTask;
|
||||
|
||||
const napi = @import("../../napi/napi.zig");
|
||||
|
||||
const TCC = @import("../../tcc.zig");
|
||||
extern fn pthread_jit_write_protect_np(enable: bool) callconv(.C) void;
|
||||
|
||||
@@ -446,7 +448,7 @@ pub const FFI = struct {
|
||||
|
||||
for (this.symbols.map.values()) |*symbol| {
|
||||
if (symbol.needsNapiEnv()) {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalThis);
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalThis.makeNapiEnvForFFI());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -803,12 +805,14 @@ pub const FFI = struct {
|
||||
// we are unable to free memory safely in certain cases here.
|
||||
}
|
||||
|
||||
const napi_env = makeNapiEnvIfNeeded(compile_c.symbols.map.values(), globalThis);
|
||||
|
||||
var obj = JSC.JSValue.createEmptyObject(globalThis, compile_c.symbols.map.count());
|
||||
for (compile_c.symbols.map.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
const allocator = bun.default_allocator;
|
||||
|
||||
function.compile(allocator, globalThis) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
if (!globalThis.hasException()) {
|
||||
const ret = JSC.toInvalidArguments("{s} when translating symbol \"{s}\"", .{
|
||||
@errorName(err),
|
||||
@@ -1129,6 +1133,9 @@ pub const FFI = struct {
|
||||
var obj = JSC.JSValue.createEmptyObject(global, size);
|
||||
obj.protect();
|
||||
defer obj.unprotect();
|
||||
|
||||
const napi_env = makeNapiEnvIfNeeded(symbols.values(), global);
|
||||
|
||||
for (symbols.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
|
||||
@@ -1148,7 +1155,7 @@ pub const FFI = struct {
|
||||
function.symbol_from_dynamic_library = resolved_symbol;
|
||||
}
|
||||
|
||||
function.compile(allocator, global) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
const ret = JSC.toInvalidArguments("{s} when compiling symbol \"{s}\" in \"{s}\"", .{
|
||||
bun.asByteSlice(@errorName(err)),
|
||||
bun.asByteSlice(function_name),
|
||||
@@ -1240,6 +1247,8 @@ pub const FFI = struct {
|
||||
var obj = JSValue.createEmptyObject(global, symbols.count());
|
||||
obj.ensureStillAlive();
|
||||
defer obj.ensureStillAlive();
|
||||
const napi_env = makeNapiEnvIfNeeded(symbols.values(), global);
|
||||
|
||||
for (symbols.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
|
||||
@@ -1253,7 +1262,7 @@ pub const FFI = struct {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function.compile(allocator, global) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
const ret = JSC.toInvalidArguments("{s} when compiling symbol \"{s}\"", .{
|
||||
bun.asByteSlice(@errorName(err)),
|
||||
bun.asByteSlice(function_name),
|
||||
@@ -1562,7 +1571,7 @@ pub const FFI = struct {
|
||||
pub fn compile(
|
||||
this: *Function,
|
||||
allocator: std.mem.Allocator,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
napiEnv: ?*napi.NapiEnv,
|
||||
) !void {
|
||||
var source_code = std.ArrayList(u8).init(allocator);
|
||||
var source_code_writer = source_code.writer();
|
||||
@@ -1585,7 +1594,9 @@ pub const FFI = struct {
|
||||
|
||||
_ = TCC.tcc_set_output_type(state, TCC.TCC_OUTPUT_MEMORY);
|
||||
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalObject);
|
||||
if (napiEnv) |env| {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", env);
|
||||
}
|
||||
|
||||
CompilerRT.define(state);
|
||||
|
||||
@@ -1694,7 +1705,9 @@ pub const FFI = struct {
|
||||
|
||||
_ = TCC.tcc_set_output_type(state, TCC.TCC_OUTPUT_MEMORY);
|
||||
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", js_context);
|
||||
if (this.needsNapiEnv()) {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", js_context.makeNapiEnvForFFI());
|
||||
}
|
||||
|
||||
CompilerRT.define(state);
|
||||
|
||||
@@ -2553,3 +2566,13 @@ const CompilerRT = struct {
|
||||
};
|
||||
|
||||
pub const Bun__FFI__cc = FFI.Bun__FFI__cc;
|
||||
|
||||
fn makeNapiEnvIfNeeded(functions: []const FFI.Function, globalThis: *JSGlobalObject) ?*napi.NapiEnv {
|
||||
for (functions) |function| {
|
||||
if (function.needsNapiEnv()) {
|
||||
return globalThis.makeNapiEnvForFFI();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,10 @@ RefPtr<JSC::SourceProvider> createBuiltinsSourceProvider();
|
||||
|
||||
JSHeapData::JSHeapData(Heap& heap)
|
||||
: m_heapCellTypeForJSWorkerGlobalScope(JSC::IsoHeapCellType::Args<Zig::GlobalObject>())
|
||||
, m_domBuiltinConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMBuiltinConstructorBase)
|
||||
, m_domConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMConstructorBase)
|
||||
, m_domNamespaceObjectSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMObject)
|
||||
, m_subspaces(makeUnique<ExtendedDOMIsoSubspaces>())
|
||||
|
||||
, m_domConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMConstructorBase)
|
||||
, m_domBuiltinConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMBuiltinConstructorBase)
|
||||
, m_domNamespaceObjectSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMObject)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,8 +43,8 @@ JSVMClientData::JSVMClientData(VM& vm, RefPtr<SourceProvider> sourceProvider)
|
||||
: m_builtinNames(vm)
|
||||
, m_builtinFunctions(vm, sourceProvider, m_builtinNames)
|
||||
, m_heapData(JSHeapData::ensureHeapData(vm.heap))
|
||||
, CLIENT_ISO_SUBSPACE_INIT(m_domBuiltinConstructorSpace)
|
||||
, CLIENT_ISO_SUBSPACE_INIT(m_domConstructorSpace)
|
||||
, CLIENT_ISO_SUBSPACE_INIT(m_domBuiltinConstructorSpace)
|
||||
, CLIENT_ISO_SUBSPACE_INIT(m_domNamespaceObjectSpace)
|
||||
, m_clientSubspaces(makeUnique<ExtendedDOMClientIsoSubspaces>())
|
||||
{
|
||||
|
||||
@@ -16,9 +16,9 @@ public:
|
||||
using BunInspectorSocket = uWS::WebSocket<isSSL, true, BunInspectorConnection*>;
|
||||
|
||||
BunInspectorConnection(BunInspectorSocket* ws, JSC::JSGlobalObject* globalObject)
|
||||
: ws(ws)
|
||||
: pendingMessages()
|
||||
, globalObject(globalObject)
|
||||
, pendingMessages()
|
||||
, ws(ws)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -394,22 +394,16 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject* globalObject,
|
||||
JSC::EncodedJSValue exports);
|
||||
napi_value (*napi_register_module_v1)(napi_env env, napi_value exports);
|
||||
#if OS(WINDOWS)
|
||||
#define dlsym GetProcAddress
|
||||
#endif
|
||||
|
||||
// TODO(@190n) look for node_register_module_vXYZ according to BuildOptions.reported_nodejs_version
|
||||
// (bun/src/env.zig:36) and the table at https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
|
||||
napi_register_module_v1 = reinterpret_cast<JSC::EncodedJSValue (*)(JSC::JSGlobalObject*,
|
||||
JSC::EncodedJSValue)>(
|
||||
napi_register_module_v1 = reinterpret_cast<napi_value (*)(napi_env, napi_value)>(
|
||||
dlsym(handle, "napi_register_module_v1"));
|
||||
|
||||
#if OS(WINDOWS)
|
||||
#undef dlsym
|
||||
#endif
|
||||
|
||||
if (!napi_register_module_v1) {
|
||||
#if OS(WINDOWS)
|
||||
FreeLibrary(handle);
|
||||
@@ -420,10 +414,35 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
|
||||
return {};
|
||||
}
|
||||
|
||||
auto node_api_module_get_api_version_v1 = reinterpret_cast<int32_t (*)()>(dlsym(handle, "node_api_module_get_api_version_v1"));
|
||||
|
||||
#if OS(WINDOWS)
|
||||
#undef dlsym
|
||||
#endif
|
||||
|
||||
NapiHandleScope handleScope(globalObject);
|
||||
|
||||
int module_version = 8;
|
||||
if (node_api_module_get_api_version_v1) {
|
||||
module_version = node_api_module_get_api_version_v1();
|
||||
}
|
||||
|
||||
napi_module nmodule {
|
||||
.nm_version = module_version,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = "file://",
|
||||
.nm_register_func = nullptr,
|
||||
.nm_modname = "[no modname]",
|
||||
.nm_priv = nullptr,
|
||||
.reserved = {},
|
||||
};
|
||||
|
||||
static_assert(sizeof(napi_value) == sizeof(EncodedJSValue), "EncodedJSValue must be reinterpretable as a pointer");
|
||||
|
||||
auto env = globalObject->makeNapiEnv(nmodule);
|
||||
|
||||
EncodedJSValue exportsValue = JSC::JSValue::encode(exports);
|
||||
JSC::JSValue resultValue = JSValue::decode(napi_register_module_v1(globalObject, exportsValue));
|
||||
JSC::JSValue resultValue = JSValue::decode(reinterpret_cast<EncodedJSValue>(napi_register_module_v1(env, reinterpret_cast<napi_value>(exportsValue))));
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
|
||||
@@ -117,10 +117,10 @@ BunString fromJS(JSC::JSGlobalObject* globalObject, JSValue value)
|
||||
{
|
||||
WTF::String str = value.toWTFString(globalObject);
|
||||
if (UNLIKELY(str.isNull())) {
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { ZigStringEmpty } };
|
||||
}
|
||||
if (UNLIKELY(str.length() == 0)) {
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
}
|
||||
|
||||
auto impl = str.releaseImpl();
|
||||
@@ -147,10 +147,10 @@ BunString toStringRef(JSC::JSGlobalObject* globalObject, JSValue value)
|
||||
{
|
||||
auto str = value.toWTFString(globalObject);
|
||||
if (UNLIKELY(str.isNull())) {
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { ZigStringEmpty } };
|
||||
}
|
||||
if (UNLIKELY(str.length() == 0)) {
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
}
|
||||
|
||||
StringImpl* impl = str.impl();
|
||||
@@ -163,21 +163,21 @@ BunString toStringRef(JSC::JSGlobalObject* globalObject, JSValue value)
|
||||
BunString toString(WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toString(const WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toString(WTF::StringImpl* wtfString)
|
||||
{
|
||||
if (wtfString->isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
|
||||
}
|
||||
@@ -185,7 +185,7 @@ BunString toString(WTF::StringImpl* wtfString)
|
||||
BunString toStringRef(WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
wtfString.impl()->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
@@ -193,7 +193,7 @@ BunString toStringRef(WTF::String& wtfString)
|
||||
BunString toStringRef(const WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
wtfString.impl()->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
@@ -201,7 +201,7 @@ BunString toStringRef(const WTF::String& wtfString)
|
||||
BunString toStringRef(WTF::StringImpl* wtfString)
|
||||
{
|
||||
if (wtfString->isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
return { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
wtfString->ref();
|
||||
|
||||
@@ -229,7 +229,7 @@ extern "C" BunString BunString__fromUTF16Unitialized(size_t length)
|
||||
UChar* ptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
|
||||
}
|
||||
@@ -240,7 +240,7 @@ extern "C" BunString BunString__fromLatin1Unitialized(size_t length)
|
||||
LChar* ptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
|
||||
}
|
||||
@@ -253,7 +253,7 @@ extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
|
||||
UChar* ptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(static_cast<unsigned int>(u16Length), ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
RELEASE_ASSERT(simdutf::convert_utf8_to_utf16(bytes, length, ptr) == u16Length);
|
||||
impl->ref();
|
||||
@@ -262,7 +262,7 @@ extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
|
||||
|
||||
auto str = WTF::String::fromUTF8ReplacingInvalidSequences(std::span { reinterpret_cast<const LChar*>(bytes), length });
|
||||
if (UNLIKELY(str.isNull())) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
str.impl()->ref();
|
||||
return Bun::toString(str);
|
||||
@@ -274,7 +274,7 @@ extern "C" BunString BunString__fromLatin1(const char* bytes, size_t length)
|
||||
LChar* ptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
memcpy(ptr, bytes, length);
|
||||
|
||||
@@ -289,7 +289,7 @@ extern "C" BunString BunString__fromUTF16ToLatin1(const char16_t* bytes, size_t
|
||||
LChar* ptr = nullptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(outLength, ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
|
||||
size_t latin1_length = simdutf::convert_valid_utf16le_to_latin1(bytes, length, reinterpret_cast<char*>(ptr));
|
||||
@@ -303,7 +303,7 @@ extern "C" BunString BunString__fromUTF16(const char16_t* bytes, size_t length)
|
||||
UChar* ptr;
|
||||
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
|
||||
if (UNLIKELY(!impl)) {
|
||||
return { .tag = BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
memcpy(ptr, bytes, length * sizeof(char16_t));
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
|
||||
@@ -434,14 +434,14 @@ extern "C" BunString URL__getHrefFromJS(EncodedJSValue encodedValue, JSC::JSGlob
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
|
||||
auto str = value.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, { BunStringTag::Dead });
|
||||
RETURN_IF_EXCEPTION(throwScope, (BunString { BunStringTag::Dead, { Zig::ZigStringEmpty } }));
|
||||
if (str.isEmpty()) {
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
}
|
||||
|
||||
auto url = WTF::URL(str);
|
||||
if (!url.isValid() || url.isEmpty())
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
|
||||
return Bun::toStringRef(url.string());
|
||||
}
|
||||
@@ -451,7 +451,7 @@ extern "C" BunString URL__getHref(BunString* input)
|
||||
auto&& str = input->toWTFString();
|
||||
auto url = WTF::URL(str);
|
||||
if (!url.isValid() || url.isEmpty())
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
|
||||
return Bun::toStringRef(url.string());
|
||||
}
|
||||
@@ -461,7 +461,7 @@ extern "C" BunString URL__pathFromFileURL(BunString* input)
|
||||
auto&& str = input->toWTFString();
|
||||
auto url = WTF::URL(str);
|
||||
if (!url.isValid() || url.isEmpty())
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
|
||||
return Bun::toStringRef(url.fileSystemPath());
|
||||
}
|
||||
@@ -472,7 +472,7 @@ extern "C" BunString URL__getHrefJoin(BunString* baseStr, BunString* relativeStr
|
||||
auto relative = relativeStr->toWTFString();
|
||||
auto url = WTF::URL(WTF::URL(base), relative);
|
||||
if (!url.isValid() || url.isEmpty())
|
||||
return { BunStringTag::Dead };
|
||||
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
|
||||
|
||||
return Bun::toStringRef(url.string());
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "JavaScriptCore/Synchronousness.h"
|
||||
#include "JavaScriptCore/JSCast.h"
|
||||
#include <JavaScriptCore/JSMapInlines.h>
|
||||
#include "helpers.h"
|
||||
#include "root.h"
|
||||
#include "JavaScriptCore/SourceCode.h"
|
||||
#include "headers-handwritten.h"
|
||||
@@ -1028,7 +1029,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
||||
|
||||
BunString specifierStr = Bun::toString(specifier);
|
||||
BunString referrerStr = Bun::toString(referrer);
|
||||
BunString typeAttributeStr = { BunStringTag::Dead };
|
||||
BunString typeAttributeStr = { BunStringTag::Dead, { ZigStringEmpty } };
|
||||
String typeAttribute = String();
|
||||
|
||||
// We need to be able to wire in the "type" import attribute from bundled code..
|
||||
|
||||
@@ -40,8 +40,8 @@ void Bun__LifecycleAgentStopPreventingExit(Inspector::InspectorLifecycleAgent* a
|
||||
InspectorLifecycleAgent::InspectorLifecycleAgent(JSC::JSGlobalObject& globalObject)
|
||||
: InspectorAgentBase("LifecycleReporter"_s)
|
||||
, m_globalObject(globalObject)
|
||||
, m_backendDispatcher(LifecycleReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
|
||||
, m_frontendDispatcher(makeUnique<LifecycleReporterFrontendDispatcher>(const_cast<FrontendRouter&>(m_globalObject.inspectorController().frontendRouter())))
|
||||
, m_backendDispatcher(LifecycleReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ void Bun__TestReporterAgentReportTestEnd(Inspector::InspectorTestReporterAgent*
|
||||
InspectorTestReporterAgent::InspectorTestReporterAgent(JSC::JSGlobalObject& globalObject)
|
||||
: InspectorAgentBase("TestReporter"_s)
|
||||
, m_globalObject(globalObject)
|
||||
, m_backendDispatcher(TestReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
|
||||
, m_frontendDispatcher(makeUnique<TestReporterFrontendDispatcher>(const_cast<FrontendRouter&>(m_globalObject.inspectorController().frontendRouter())))
|
||||
, m_backendDispatcher(TestReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1996,7 +1996,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array
|
||||
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
|
||||
IGNORE_WARNINGS_END
|
||||
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
|
||||
return { allocBuffer(lexicalGlobalObject, byteLength) };
|
||||
return { allocBuffer(lexicalGlobalObject, byteLength), nullptr };
|
||||
}
|
||||
|
||||
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength))
|
||||
@@ -2006,7 +2006,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint
|
||||
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
|
||||
IGNORE_WARNINGS_END
|
||||
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
|
||||
return { allocBufferUnsafe(lexicalGlobalObject, byteLength) };
|
||||
return { allocBufferUnsafe(lexicalGlobalObject, byteLength), nullptr };
|
||||
}
|
||||
|
||||
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength))
|
||||
@@ -2016,7 +2016,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JS
|
||||
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
|
||||
IGNORE_WARNINGS_END
|
||||
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
|
||||
return { allocBufferUnsafe(lexicalGlobalObject, byteLength) };
|
||||
return { allocBufferUnsafe(lexicalGlobalObject, byteLength), nullptr };
|
||||
}
|
||||
|
||||
JSC_ANNOTATE_HOST_FUNCTION(JSBufferConstructorConstruct, JSBufferConstructor::construct);
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
const CFFIFunction function() const { return m_function; }
|
||||
inline CFFIFunction function() const { return m_function; }
|
||||
|
||||
#if OS(WINDOWS)
|
||||
|
||||
@@ -86,14 +86,14 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
void* dataPtr;
|
||||
void* dataPtr = nullptr;
|
||||
|
||||
private:
|
||||
JSFFIFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, CFFIFunction&&);
|
||||
void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name);
|
||||
DECLARE_VISIT_CHILDREN;
|
||||
|
||||
CFFIFunction m_function;
|
||||
CFFIFunction m_function = nullptr;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
@@ -18,8 +18,8 @@ using namespace JSC;
|
||||
class JSPropertyIterator {
|
||||
public:
|
||||
JSPropertyIterator(JSC::VM& m_vm, RefPtr<JSC::PropertyNameArrayData> m_properties)
|
||||
: vm(m_vm)
|
||||
, properties(m_properties)
|
||||
: properties(m_properties)
|
||||
, vm(m_vm)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" SerializedValueSlice Bun__serializeJSValue(JSGlobalObject* globalObje
|
||||
if (serialized.hasException()) {
|
||||
WebCore::propagateException(*globalObject, scope,
|
||||
serialized.releaseException());
|
||||
RELEASE_AND_RETURN(scope, { 0 });
|
||||
RELEASE_AND_RETURN(scope, (SerializedValueSlice { nullptr, 0, nullptr }));
|
||||
}
|
||||
|
||||
auto serializedValue = serialized.releaseReturnValue();
|
||||
|
||||
@@ -1204,9 +1204,8 @@ GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure, WebCore::Scri
|
||||
|
||||
GlobalObject::~GlobalObject()
|
||||
{
|
||||
if (napiInstanceDataFinalizer) {
|
||||
napi_finalize finalizer = reinterpret_cast<napi_finalize>(napiInstanceDataFinalizer);
|
||||
finalizer(toNapi(this), napiInstanceData, napiInstanceDataFinalizerHint);
|
||||
for (const auto& env : m_napiEnvs) {
|
||||
env->cleanup();
|
||||
}
|
||||
|
||||
if (auto* ctx = scriptExecutionContext()) {
|
||||
@@ -2487,6 +2486,11 @@ extern "C" JSC__JSValue ZigGlobalObject__readableStreamToBlob(Zig::GlobalObject*
|
||||
return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments));
|
||||
}
|
||||
|
||||
extern "C" napi_env ZigGlobalObject__makeNapiEnvForFFI(Zig::GlobalObject* globalObject)
|
||||
{
|
||||
return globalObject->makeNapiEnvForFFI();
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(functionReadableStreamToArrayBuffer);
|
||||
JSC_DEFINE_HOST_FUNCTION(functionReadableStreamToArrayBuffer, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
@@ -4354,6 +4358,26 @@ GlobalObject::PromiseFunctions GlobalObject::promiseHandlerID(Zig::FFIFunction h
|
||||
}
|
||||
}
|
||||
|
||||
napi_env GlobalObject::makeNapiEnv(const napi_module& mod)
|
||||
{
|
||||
m_napiEnvs.append(std::make_unique<napi_env__>(this, mod));
|
||||
return m_napiEnvs.last().get();
|
||||
}
|
||||
|
||||
napi_env GlobalObject::makeNapiEnvForFFI()
|
||||
{
|
||||
auto out = makeNapiEnv(napi_module {
|
||||
.nm_version = 9,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = "ffi://",
|
||||
.nm_register_func = nullptr,
|
||||
.nm_modname = "[ffi]",
|
||||
.nm_priv = nullptr,
|
||||
.reserved = {},
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "ZigGeneratedClasses+lazyStructureImpl.h"
|
||||
#include "ZigGlobalObject.lut.h"
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ class GlobalInternals;
|
||||
#include "BunHttp2CommonStrings.h"
|
||||
#include "BunGlobalScope.h"
|
||||
|
||||
typedef struct napi_env__* napi_env;
|
||||
struct napi_module;
|
||||
|
||||
namespace WebCore {
|
||||
class WorkerGlobalScope;
|
||||
class SubtleCrypto;
|
||||
@@ -446,13 +449,6 @@ public:
|
||||
// To do that, we count the number of times we register a module.
|
||||
int napiModuleRegisterCallCount = 0;
|
||||
|
||||
// NAPI instance data
|
||||
// This is not a correct implementation
|
||||
// Addon modules can override each other's data
|
||||
void* napiInstanceData = nullptr;
|
||||
void* napiInstanceDataFinalizer = nullptr;
|
||||
void* napiInstanceDataFinalizerHint = nullptr;
|
||||
|
||||
// Used by napi_type_tag_object to associate a 128-bit type ID with JS objects.
|
||||
// Should only use JSCell* keys and NapiTypeTag values.
|
||||
LazyProperty<JSGlobalObject, JSC::JSWeakMap> m_napiTypeTags;
|
||||
@@ -573,6 +569,10 @@ public:
|
||||
|
||||
bool hasOverridenModuleResolveFilenameFunction = false;
|
||||
|
||||
WTF::Vector<std::unique_ptr<napi_env__>, 0> m_napiEnvs;
|
||||
napi_env makeNapiEnv(const napi_module&);
|
||||
napi_env makeNapiEnvForFFI();
|
||||
|
||||
private:
|
||||
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
|
||||
WebCore::SubtleCrypto* m_subtleCrypto = nullptr;
|
||||
|
||||
@@ -252,7 +252,7 @@ void SourceProvider::freeSourceCode()
|
||||
|
||||
void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&,
|
||||
CodeSpecializationKind kind,
|
||||
const UnlinkedFunctionCodeBlock* codeBlock)
|
||||
const UnlinkedFunctionCodeBlock* codeBlock) const
|
||||
{
|
||||
// if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode)
|
||||
return;
|
||||
@@ -263,7 +263,7 @@ void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, c
|
||||
m_cachedBytecode->addFunctionUpdate(executable, kind, *cachedBytecode);
|
||||
}
|
||||
|
||||
void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator)
|
||||
void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator) const
|
||||
{
|
||||
// if (!m_resolvedSource.bytecodecache_fd)
|
||||
return;
|
||||
@@ -275,7 +275,7 @@ void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator)
|
||||
m_cachedBytecode->addGlobalUpdate(*update);
|
||||
}
|
||||
|
||||
void SourceProvider::commitCachedBytecode()
|
||||
void SourceProvider::commitCachedBytecode() const
|
||||
{
|
||||
// if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode || !m_cachedBytecode->hasUpdates())
|
||||
return;
|
||||
|
||||
@@ -51,9 +51,9 @@ public:
|
||||
};
|
||||
|
||||
void updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&,
|
||||
CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock);
|
||||
void cacheBytecode(const BytecodeCacheGenerator& generator);
|
||||
void commitCachedBytecode();
|
||||
CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock) const final;
|
||||
void cacheBytecode(const BytecodeCacheGenerator& generator) const final;
|
||||
void commitCachedBytecode() const final;
|
||||
bool isBytecodeCacheEnabled() const;
|
||||
void readOrGenerateByteCodeCache(JSC::VM& vm, const JSC::SourceCode& sourceCode);
|
||||
ResolvedSource m_resolvedSource;
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
}
|
||||
|
||||
Zig::GlobalObject* m_globalObject;
|
||||
RefPtr<JSC::CachedBytecode> m_cachedBytecode;
|
||||
mutable RefPtr<JSC::CachedBytecode> m_cachedBytecode;
|
||||
Ref<WTF::StringImpl> m_source;
|
||||
unsigned m_hash = 0;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
const napi = @import("../../napi/napi.zig");
|
||||
|
||||
pub const JSObject = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSObject", @This());
|
||||
@@ -3519,6 +3520,12 @@ pub const JSGlobalObject = opaque {
|
||||
return ZigGlobalObject__readableStreamToFormData(this, value, content_type);
|
||||
}
|
||||
|
||||
extern fn ZigGlobalObject__makeNapiEnvForFFI(*JSGlobalObject) *napi.NapiEnv;
|
||||
|
||||
pub fn makeNapiEnvForFFI(this: *JSGlobalObject) *napi.NapiEnv {
|
||||
return ZigGlobalObject__makeNapiEnvForFFI(this);
|
||||
}
|
||||
|
||||
pub inline fn assertOnJSThread(this: *JSGlobalObject) void {
|
||||
if (bun.Environment.allow_assert) this.bunVM().assertOnJSThread();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "root.h"
|
||||
|
||||
typedef struct FFIFields {
|
||||
struct FFIFields {
|
||||
uint32_t JSArrayBufferView__offsetOfLength;
|
||||
uint32_t JSArrayBufferView__offsetOfByteOffset;
|
||||
uint32_t JSArrayBufferView__offsetOfVector;
|
||||
uint32_t JSCell__offsetOfType;
|
||||
} FFIFields;
|
||||
extern "C" FFIFields Bun__FFI__offsets = { 0 };
|
||||
};
|
||||
|
||||
FFIFields Bun__FFI__offsets = { 0, 0, 0, 0 };
|
||||
|
||||
extern "C" void Bun__FFI__ensureOffsetsAreLoaded()
|
||||
{
|
||||
|
||||
@@ -12,10 +12,10 @@ namespace WTF {
|
||||
class String;
|
||||
}
|
||||
|
||||
typedef struct ZigString {
|
||||
struct ZigString {
|
||||
const unsigned char* ptr;
|
||||
size_t len;
|
||||
} ZigString;
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef uint8_t BunStringTag;
|
||||
@@ -30,10 +30,10 @@ class StringImpl;
|
||||
class String;
|
||||
}
|
||||
|
||||
typedef union BunStringImpl {
|
||||
union BunStringImpl {
|
||||
ZigString zig;
|
||||
WTF::StringImpl* wtf;
|
||||
} BunStringImpl;
|
||||
};
|
||||
|
||||
enum class BunStringTag : uint8_t {
|
||||
Dead = 0,
|
||||
@@ -44,7 +44,7 @@ enum class BunStringTag : uint8_t {
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct BunString {
|
||||
struct BunString {
|
||||
BunStringTag tag;
|
||||
BunStringImpl impl;
|
||||
|
||||
@@ -67,30 +67,29 @@ typedef struct BunString {
|
||||
|
||||
// This one usually will clone the raw bytes.
|
||||
WTF::String toWTFString() const;
|
||||
};
|
||||
|
||||
} BunString;
|
||||
|
||||
typedef struct ZigErrorType {
|
||||
struct ZigErrorType {
|
||||
ZigErrorCode code;
|
||||
void* ptr;
|
||||
} ZigErrorType;
|
||||
typedef union ErrorableZigStringResult {
|
||||
};
|
||||
union ErrorableZigStringResult {
|
||||
ZigString value;
|
||||
ZigErrorType err;
|
||||
} ErrorableZigStringResult;
|
||||
typedef struct ErrorableZigString {
|
||||
};
|
||||
struct ErrorableZigString {
|
||||
ErrorableZigStringResult result;
|
||||
bool success;
|
||||
} ErrorableZigString;
|
||||
typedef union ErrorableStringResult {
|
||||
};
|
||||
union ErrorableStringResult {
|
||||
BunString value;
|
||||
ZigErrorType err;
|
||||
} ErrorableStringResult;
|
||||
typedef struct ErrorableString {
|
||||
};
|
||||
struct ErrorableString {
|
||||
ErrorableStringResult result;
|
||||
bool success;
|
||||
} ErrorableString;
|
||||
typedef struct ResolvedSource {
|
||||
};
|
||||
struct ResolvedSource {
|
||||
BunString specifier;
|
||||
BunString source_code;
|
||||
BunString source_url;
|
||||
@@ -103,25 +102,25 @@ typedef struct ResolvedSource {
|
||||
bool already_bundled;
|
||||
uint8_t* bytecode_cache;
|
||||
size_t bytecode_cache_size;
|
||||
} ResolvedSource;
|
||||
};
|
||||
static const uint32_t ResolvedSourceTagPackageJSONTypeModule = 1;
|
||||
typedef union ErrorableResolvedSourceResult {
|
||||
union ErrorableResolvedSourceResult {
|
||||
ResolvedSource value;
|
||||
ZigErrorType err;
|
||||
} ErrorableResolvedSourceResult;
|
||||
typedef struct ErrorableResolvedSource {
|
||||
};
|
||||
struct ErrorableResolvedSource {
|
||||
ErrorableResolvedSourceResult result;
|
||||
bool success;
|
||||
} ErrorableResolvedSource;
|
||||
};
|
||||
|
||||
typedef struct SystemError {
|
||||
struct SystemError {
|
||||
int errno_;
|
||||
BunString code;
|
||||
BunString message;
|
||||
BunString path;
|
||||
BunString syscall;
|
||||
int fd;
|
||||
} SystemError;
|
||||
};
|
||||
|
||||
typedef void* ArrayBufferSink;
|
||||
|
||||
@@ -143,7 +142,7 @@ const ZigStackFrameCode ZigStackFrameCodeConstructor = 6;
|
||||
extern "C" void __attribute((__noreturn__)) Bun__panic(const char* message, size_t length);
|
||||
#define BUN_PANIC(message) Bun__panic(message, sizeof(message) - 1)
|
||||
|
||||
typedef struct ZigStackFramePosition {
|
||||
struct ZigStackFramePosition {
|
||||
int32_t line_zero_based;
|
||||
int32_t column_zero_based;
|
||||
int32_t byte_position;
|
||||
@@ -156,17 +155,17 @@ typedef struct ZigStackFramePosition {
|
||||
{
|
||||
return OrdinalNumber::fromZeroBasedInt(this->line_zero_based);
|
||||
}
|
||||
} ZigStackFramePosition;
|
||||
};
|
||||
|
||||
typedef struct ZigStackFrame {
|
||||
struct ZigStackFrame {
|
||||
BunString function_name;
|
||||
BunString source_url;
|
||||
ZigStackFramePosition position;
|
||||
ZigStackFrameCode code_type;
|
||||
bool remapped;
|
||||
} ZigStackFrame;
|
||||
};
|
||||
|
||||
typedef struct ZigStackTrace {
|
||||
struct ZigStackTrace {
|
||||
BunString* source_lines_ptr;
|
||||
OrdinalNumber* source_lines_numbers;
|
||||
uint8_t source_lines_len;
|
||||
@@ -174,9 +173,9 @@ typedef struct ZigStackTrace {
|
||||
ZigStackFrame* frames_ptr;
|
||||
uint8_t frames_len;
|
||||
JSC::SourceProvider* referenced_source_provider;
|
||||
} ZigStackTrace;
|
||||
};
|
||||
|
||||
typedef struct ZigException {
|
||||
struct ZigException {
|
||||
unsigned char code;
|
||||
uint16_t runtime_type;
|
||||
int errno_;
|
||||
@@ -189,7 +188,7 @@ typedef struct ZigException {
|
||||
void* exception;
|
||||
bool remapped;
|
||||
int fd;
|
||||
} ZigException;
|
||||
};
|
||||
|
||||
typedef uint8_t JSErrorCode;
|
||||
const JSErrorCode JSErrorCodeError = 0;
|
||||
@@ -254,10 +253,10 @@ const ReadableEvent ReadableEventUser = 254;
|
||||
|
||||
#ifndef STRING_POINTER
|
||||
#define STRING_POINTER
|
||||
typedef struct StringPointer {
|
||||
struct StringPointer {
|
||||
uint32_t off;
|
||||
uint32_t len;
|
||||
} StringPointer;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef void WebSocketHTTPClient;
|
||||
@@ -268,9 +267,7 @@ typedef void WebSocketClientTLS;
|
||||
#ifndef __cplusplus
|
||||
typedef struct Bun__ArrayBuffer Bun__ArrayBuffer;
|
||||
typedef struct Uint8Array_alias Uint8Array_alias;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#else
|
||||
|
||||
extern "C" void Bun__WTFStringImpl__deref(WTF::StringImpl* impl);
|
||||
extern "C" void Bun__WTFStringImpl__ref(WTF::StringImpl* impl);
|
||||
@@ -298,7 +295,7 @@ BunString toStringView(WTF::StringView view);
|
||||
|
||||
using Uint8Array_alias = JSC::JSUint8Array;
|
||||
|
||||
typedef struct {
|
||||
struct Bun__ArrayBuffer {
|
||||
char* ptr;
|
||||
size_t offset;
|
||||
size_t len;
|
||||
@@ -306,7 +303,7 @@ typedef struct {
|
||||
uint8_t cell_type;
|
||||
int64_t _value;
|
||||
bool shared;
|
||||
} Bun__ArrayBuffer;
|
||||
};
|
||||
|
||||
#include "SyntheticModuleType.h"
|
||||
|
||||
|
||||
@@ -206,11 +206,10 @@ static const JSC::JSValue toJSStringValueGC(ZigString str, JSC::JSGlobalObject*
|
||||
return JSC::JSValue(toJSStringGC(str, global));
|
||||
}
|
||||
|
||||
static const ZigString ZigStringEmpty = ZigString { (unsigned char*)"", 0 };
|
||||
static const unsigned char __dot_char = '.';
|
||||
static const ZigString ZigStringCwd = ZigString { &__dot_char, 1 };
|
||||
static const BunString BunStringCwd = BunString { BunStringTag::StaticZigString, ZigStringCwd };
|
||||
static const BunString BunStringEmpty = BunString { BunStringTag::Empty, nullptr };
|
||||
static const ZigString ZigStringEmpty = ZigString { reinterpret_cast<const unsigned char*>(""), 0 };
|
||||
static const ZigString ZigStringCwd = ZigString { reinterpret_cast<const unsigned char*>("."), 1 };
|
||||
static const BunString BunStringCwd = BunString { BunStringTag::StaticZigString, { ZigStringCwd } };
|
||||
static const BunString BunStringEmpty = BunString { BunStringTag::Empty, { ZigStringEmpty } };
|
||||
|
||||
static const unsigned char* taggedUTF16Ptr(const UChar* ptr)
|
||||
{
|
||||
|
||||
@@ -120,7 +120,7 @@ JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSOb
|
||||
static inline Zig::GlobalObject* defaultGlobalObject(napi_env env)
|
||||
{
|
||||
if (env) {
|
||||
return defaultGlobalObject(toJS(env));
|
||||
return defaultGlobalObject(env->globalObject());
|
||||
}
|
||||
|
||||
return defaultGlobalObject();
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
auto finalizer = weakValue->finalizer;
|
||||
if (finalizer.finalize_cb) {
|
||||
weakValue->finalizer.finalize_cb = nullptr;
|
||||
finalizer.call(weakValue->globalObject.get(), weakValue->data);
|
||||
finalizer.call(weakValue->env, weakValue->data);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -146,11 +146,11 @@ static NapiRefWeakHandleOwner& weakValueHandleOwner()
|
||||
return jscWeakValueHandleOwner;
|
||||
}
|
||||
|
||||
void NapiFinalizer::call(JSC::JSGlobalObject* globalObject, void* data)
|
||||
void NapiFinalizer::call(napi_env env, void* data)
|
||||
{
|
||||
if (this->finalize_cb) {
|
||||
NAPI_PREMABLE
|
||||
this->finalize_cb(toNapi(globalObject), data, this->finalize_hint);
|
||||
this->finalize_cb(env, data, this->finalize_hint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ void NapiRef::unref()
|
||||
|
||||
void NapiRef::clear()
|
||||
{
|
||||
this->finalizer.call(this->globalObject.get(), this->data);
|
||||
this->finalizer.call(this->env, this->data);
|
||||
this->globalObject.clear();
|
||||
this->weakValueRef.clear();
|
||||
this->strongRef.clear();
|
||||
@@ -432,7 +432,6 @@ public:
|
||||
{
|
||||
ASSERT(jsCast<NAPIFunction*>(callframe->jsCallee()));
|
||||
auto* function = static_cast<NAPIFunction*>(callframe->jsCallee());
|
||||
auto* env = toNapi(globalObject);
|
||||
auto* callback = reinterpret_cast<napi_callback>(function->m_method);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
@@ -446,28 +445,29 @@ public:
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
Bun::NapiHandleScope handleScope(jsCast<Zig::GlobalObject*>(globalObject));
|
||||
|
||||
auto result = callback(env, NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
auto result = callback(function->m_env, NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
|
||||
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(toJS(result)));
|
||||
}
|
||||
|
||||
NAPIFunction(JSC::VM& vm, JSC::NativeExecutable* exec, JSGlobalObject* globalObject, Structure* structure, Zig::CFFIFunction method, void* dataPtr)
|
||||
NAPIFunction(JSC::VM& vm, JSC::NativeExecutable* exec, JSGlobalObject* globalObject, Structure* structure, Zig::CFFIFunction method, void* dataPtr, napi_env env)
|
||||
: Base(vm, exec, globalObject, structure)
|
||||
, m_method(method)
|
||||
, m_env(env)
|
||||
, m_dataPtr(dataPtr)
|
||||
, m_method(method)
|
||||
{
|
||||
}
|
||||
|
||||
static NAPIFunction* create(JSC::VM& vm, Zig::GlobalObject* globalObject, unsigned length, const WTF::String& name, Zig::CFFIFunction method, void* dataPtr)
|
||||
static NAPIFunction* create(JSC::VM& vm, Zig::GlobalObject* globalObject, unsigned length, const WTF::String& name, Zig::CFFIFunction method, void* dataPtr, napi_env env)
|
||||
{
|
||||
|
||||
auto* structure = globalObject->NAPIFunctionStructure();
|
||||
NativeExecutable* executable = vm.getHostFunction(&NAPIFunction::call, ImplementationVisibility::Public, &NAPIFunction::call, name);
|
||||
NAPIFunction* functionObject = new (NotNull, JSC::allocateCell<NAPIFunction>(vm)) NAPIFunction(vm, executable, globalObject, structure, method, dataPtr);
|
||||
NAPIFunction* functionObject = new (NotNull, JSC::allocateCell<NAPIFunction>(vm)) NAPIFunction(vm, executable, globalObject, structure, method, dataPtr, env);
|
||||
functionObject->finishCreation(vm, executable, length, name);
|
||||
return functionObject;
|
||||
}
|
||||
|
||||
napi_env m_env = nullptr;
|
||||
void* m_dataPtr = nullptr;
|
||||
Zig::CFFIFunction m_method = nullptr;
|
||||
|
||||
@@ -501,8 +501,9 @@ Structure* Zig::createNAPIFunctionStructure(VM& vm, JSC::JSGlobalObject* globalO
|
||||
return NAPIFunction::createStructure(vm, globalObject, prototype);
|
||||
}
|
||||
|
||||
static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance, JSC::ThrowScope& scope)
|
||||
static void defineNapiProperty(napi_env env, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance, JSC::ThrowScope& scope)
|
||||
{
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
void* dataPtr = property.data;
|
||||
if (!dataPtr) {
|
||||
@@ -535,7 +536,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
JSC::JSValue value;
|
||||
auto method = reinterpret_cast<Zig::CFFIFunction>(property.method);
|
||||
|
||||
auto* function = NAPIFunction::create(vm, globalObject, 1, propertyName.isSymbol() ? String() : propertyName.string(), method, dataPtr);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, 1, propertyName.isSymbol() ? String() : propertyName.string(), method, dataPtr, env);
|
||||
value = JSC::JSValue(function);
|
||||
|
||||
to->putDirect(vm, propertyName, value, getPropertyAttributes(property));
|
||||
@@ -550,7 +551,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
auto setterProperty = reinterpret_cast<CFFIFunction>(property.setter);
|
||||
|
||||
if (getterProperty) {
|
||||
getter = NAPIFunction::create(vm, globalObject, 0, makeString("get "_s, propertyName.isSymbol() ? String() : propertyName.string()), getterProperty, dataPtr);
|
||||
getter = NAPIFunction::create(vm, globalObject, 0, makeString("get "_s, propertyName.isSymbol() ? String() : propertyName.string()), getterProperty, dataPtr, env);
|
||||
} else {
|
||||
JSC::JSNativeStdFunction* getterFunction = JSC::JSNativeStdFunction::create(
|
||||
globalObject->vm(), globalObject, 0, String(), [](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
|
||||
@@ -560,7 +561,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
}
|
||||
|
||||
if (setterProperty) {
|
||||
setter = NAPIFunction::create(vm, globalObject, 1, makeString("set "_s, propertyName.isSymbol() ? String() : propertyName.string()), setterProperty, dataPtr);
|
||||
setter = NAPIFunction::create(vm, globalObject, 1, makeString("set "_s, propertyName.isSymbol() ? String() : propertyName.string()), setterProperty, dataPtr, env);
|
||||
} else {
|
||||
JSC::JSNativeStdFunction* setterFunction = JSC::JSNativeStdFunction::create(
|
||||
globalObject->vm(), globalObject, 1, String(), [](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
|
||||
@@ -596,7 +597,7 @@ extern "C" napi_status napi_set_property(napi_env env, napi_value target,
|
||||
return napi_object_expected;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
auto* object = targetValue.toObject(globalObject);
|
||||
@@ -636,7 +637,7 @@ extern "C" napi_status napi_has_property(napi_env env, napi_value object,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
auto* target = toJS(object).toObject(globalObject);
|
||||
@@ -690,7 +691,7 @@ extern "C" napi_status napi_get_property(napi_env env, napi_value object,
|
||||
return napi_object_expected;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
@@ -712,7 +713,7 @@ extern "C" napi_status napi_delete_property(napi_env env, napi_value object,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
@@ -739,7 +740,7 @@ extern "C" napi_status napi_has_own_property(napi_env env, napi_value object,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
@@ -760,7 +761,7 @@ extern "C" napi_status napi_set_named_property(napi_env env, napi_value object,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
auto target = toJS(object).toObject(globalObject);
|
||||
@@ -792,7 +793,7 @@ extern "C" napi_status napi_create_arraybuffer(napi_env env,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
if (UNLIKELY(!globalObject || !result)) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
@@ -840,7 +841,7 @@ extern "C" napi_status napi_has_named_property(napi_env env, napi_value object,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
@@ -866,7 +867,7 @@ extern "C" napi_status napi_get_named_property(napi_env env, napi_value object,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
auto scope = DECLARE_CATCH_SCOPE(vm);
|
||||
@@ -900,15 +901,15 @@ node_api_create_external_string_latin1(napi_env env,
|
||||
}
|
||||
|
||||
length = length == NAPI_AUTO_LENGTH ? strlen(str) : length;
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const LChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const LChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback, env](void* hint, void* str, unsigned length) {
|
||||
if (finalize_callback) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] string finalize_callback\n");
|
||||
#endif
|
||||
finalize_callback(toNapi(defaultGlobalObject()), nullptr, hint);
|
||||
finalize_callback(env, nullptr, hint);
|
||||
}
|
||||
});
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
|
||||
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
|
||||
ensureStillAliveHere(out);
|
||||
@@ -937,16 +938,16 @@ node_api_create_external_string_utf16(napi_env env,
|
||||
}
|
||||
|
||||
length = length == NAPI_AUTO_LENGTH ? std::char_traits<char16_t>::length(str) : length;
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const UChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const UChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback, env](void* hint, void* str, unsigned length) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] string finalize_callback\n");
|
||||
#endif
|
||||
|
||||
if (finalize_callback) {
|
||||
finalize_callback(toNapi(defaultGlobalObject()), nullptr, hint);
|
||||
finalize_callback(env, nullptr, hint);
|
||||
}
|
||||
});
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
|
||||
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
|
||||
ensureStillAliveHere(out);
|
||||
@@ -959,6 +960,7 @@ extern "C" size_t Bun__napi_module_register_count;
|
||||
extern "C" void napi_module_register(napi_module* mod)
|
||||
{
|
||||
auto* globalObject = defaultGlobalObject();
|
||||
napi_env env = globalObject->makeNapiEnv(*mod);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto keyStr = WTF::String::fromUTF8(mod->nm_modname);
|
||||
globalObject->napiModuleRegisterCallCount++;
|
||||
@@ -988,7 +990,7 @@ extern "C" void napi_module_register(napi_module* mod)
|
||||
JSC::Strong<JSC::JSObject> strongObject = { vm, object };
|
||||
|
||||
Bun::NapiHandleScope handleScope(globalObject);
|
||||
JSValue resultValue = toJS(mod->nm_register_func(toNapi(globalObject), toNapi(object, globalObject)));
|
||||
JSValue resultValue = toJS(mod->nm_register_func(env, toNapi(object, globalObject)));
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, void());
|
||||
|
||||
@@ -1033,8 +1035,6 @@ extern "C" napi_status napi_wrap(napi_env env,
|
||||
return napi_object_expected;
|
||||
}
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
|
||||
NapiRef** refPtr = nullptr;
|
||||
if (auto* val = jsDynamicCast<NapiPrototype*>(value)) {
|
||||
refPtr = &val->napiRef;
|
||||
@@ -1053,7 +1053,7 @@ extern "C" napi_status napi_wrap(napi_env env,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto* ref = new NapiRef(globalObject, 0);
|
||||
auto* ref = new NapiRef(env, 0);
|
||||
|
||||
ref->weakValueRef.set(value, weakValueHandleOwner(), ref);
|
||||
|
||||
@@ -1149,7 +1149,7 @@ extern "C" napi_status napi_create_function(napi_env env, const char* utf8name,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto name = WTF::String();
|
||||
|
||||
@@ -1158,7 +1158,7 @@ extern "C" napi_status napi_create_function(napi_env env, const char* utf8name,
|
||||
}
|
||||
|
||||
auto method = reinterpret_cast<Zig::CFFIFunction>(cb);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, length, name, method, data);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, length, name, method, data, env);
|
||||
|
||||
ASSERT(function->isCallable());
|
||||
*result = toNapi(JSC::JSValue(function), globalObject);
|
||||
@@ -1178,7 +1178,7 @@ extern "C" napi_status napi_get_cb_info(
|
||||
NAPI_PREMABLE
|
||||
|
||||
JSC::CallFrame* callFrame = reinterpret_cast<JSC::CallFrame*>(cbinfo);
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
|
||||
if (NAPICallFrame* frame = NAPICallFrame::get(callFrame).value_or(nullptr)) {
|
||||
NAPICallFrame::extract(*frame, argc, argv, this_arg, data, globalObject);
|
||||
@@ -1261,7 +1261,7 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSValue objectValue = toJS(object);
|
||||
@@ -1280,7 +1280,7 @@ 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, throwScope);
|
||||
defineNapiProperty(env, objectObject, inheritedDataPtr, properties[i], true, throwScope);
|
||||
|
||||
RETURN_IF_EXCEPTION(throwScope, napi_generic_failure);
|
||||
}
|
||||
@@ -1310,7 +1310,7 @@ static JSC::ErrorInstance* createErrorWithCode(JSC::JSGlobalObject* globalObject
|
||||
// used to implement napi_throw_*_error
|
||||
static napi_status throwErrorWithCStrings(napi_env env, const char* code_utf8, const char* msg_utf8, JSC::ErrorType type)
|
||||
{
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -1340,7 +1340,7 @@ static napi_status createErrorWithNapiValues(napi_env env, napi_value code, napi
|
||||
return napi_string_expected;
|
||||
}
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
|
||||
auto wtf_code = js_code.isEmpty() ? WTF::String() : js_code.getString(globalObject);
|
||||
auto wtf_message = js_message.getString(globalObject);
|
||||
@@ -1375,9 +1375,9 @@ extern "C" napi_status napi_create_reference(napi_env env, napi_value value,
|
||||
return napi_object_expected;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
|
||||
auto* ref = new NapiRef(globalObject, initial_refcount);
|
||||
auto* ref = new NapiRef(env, initial_refcount);
|
||||
if (initial_refcount > 0) {
|
||||
ref->strongRef.set(globalObject->vm(), val);
|
||||
}
|
||||
@@ -1409,7 +1409,7 @@ extern "C" napi_status napi_add_finalizer(napi_env env, napi_value js_object,
|
||||
if (UNLIKELY(!env)) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSValue objectValue = toJS(js_object);
|
||||
@@ -1455,7 +1455,7 @@ extern "C" napi_status napi_get_reference_value(napi_env env, napi_ref ref,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
NapiRef* napiRef = toJS(ref);
|
||||
*result = toNapi(napiRef->value(), toJS(env));
|
||||
*result = toNapi(napiRef->value(), env->globalObject());
|
||||
|
||||
return napi_ok;
|
||||
}
|
||||
@@ -1523,7 +1523,7 @@ extern "C" napi_status napi_detach_arraybuffer(napi_env env,
|
||||
napi_value arraybuffer)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSArrayBuffer* jsArrayBuffer = JSC::jsDynamicCast<JSC::JSArrayBuffer*>(toJS(arraybuffer));
|
||||
@@ -1553,9 +1553,9 @@ extern "C" napi_status napi_adjust_external_memory(napi_env env,
|
||||
}
|
||||
|
||||
if (change_in_bytes > 0) {
|
||||
toJS(env)->vm().heap.deprecatedReportExtraMemory(change_in_bytes);
|
||||
env->globalObject()->vm().heap.deprecatedReportExtraMemory(change_in_bytes);
|
||||
}
|
||||
*adjusted_value = toJS(env)->vm().heap.extraMemorySize();
|
||||
*adjusted_value = env->globalObject()->vm().heap.extraMemorySize();
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -1567,7 +1567,7 @@ extern "C" napi_status napi_is_exception_pending(napi_env env, bool* result)
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
*result = globalObject->vm().exceptionForInspection() != nullptr;
|
||||
return napi_ok;
|
||||
}
|
||||
@@ -1580,7 +1580,7 @@ extern "C" napi_status napi_get_and_clear_last_exception(napi_env env,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
|
||||
if (scope.exception()) {
|
||||
*result = toNapi(JSC::JSValue(scope.exception()->value()), globalObject);
|
||||
@@ -1595,7 +1595,7 @@ extern "C" napi_status napi_fatal_exception(napi_env env,
|
||||
napi_value err)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
JSC::JSValue value = toJS(err);
|
||||
JSC::JSObject* obj = value.getObject();
|
||||
if (UNLIKELY(obj == nullptr || !obj->isErrorInstance())) {
|
||||
@@ -1610,7 +1610,7 @@ extern "C" napi_status napi_fatal_exception(napi_env env,
|
||||
extern "C" napi_status napi_throw(napi_env env, napi_value error)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -1629,7 +1629,7 @@ extern "C" napi_status node_api_symbol_for(napi_env env,
|
||||
size_t length, napi_value* result)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
if (UNLIKELY(!result || !utf8description)) {
|
||||
return napi_invalid_arg;
|
||||
@@ -1694,7 +1694,7 @@ extern "C" napi_status napi_object_freeze(napi_env env, napi_value object_value)
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -1713,7 +1713,7 @@ extern "C" napi_status napi_object_freeze(napi_env env, napi_value object_value)
|
||||
extern "C" napi_status napi_object_seal(napi_env env, napi_value object_value)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -1739,7 +1739,7 @@ extern "C" napi_status napi_get_global(napi_env env, napi_value* result)
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
*result = toNapi(globalObject->globalThis(), globalObject);
|
||||
return napi_ok;
|
||||
}
|
||||
@@ -1767,12 +1767,12 @@ extern "C" napi_status napi_get_new_target(napi_env env,
|
||||
CallFrame* callFrame = reinterpret_cast<JSC::CallFrame*>(cbinfo);
|
||||
|
||||
if (NAPICallFrame* frame = NAPICallFrame::get(callFrame).value_or(nullptr)) {
|
||||
*result = toNapi(frame->newTarget, toJS(env));
|
||||
*result = toNapi(frame->newTarget, env->globalObject());
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
JSC::JSValue newTarget = callFrame->newTarget();
|
||||
*result = toNapi(newTarget, toJS(env));
|
||||
*result = toNapi(newTarget, env->globalObject());
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -1787,7 +1787,7 @@ extern "C" napi_status napi_create_dataview(napi_env env, size_t length,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -1814,8 +1814,7 @@ void NapiClass::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
|
||||
DEFINE_VISIT_CHILDREN(NapiClass);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(NapiClass_ConstructorFunction,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
JSC_HOST_CALL_ATTRIBUTES JSC::EncodedJSValue NapiClass_ConstructorFunction(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
@@ -1853,12 +1852,12 @@ JSC_DEFINE_HOST_FUNCTION(NapiClass_ConstructorFunction,
|
||||
frame.newTarget = newTarget;
|
||||
Bun::NapiHandleScope handleScope(jsCast<Zig::GlobalObject*>(globalObject));
|
||||
|
||||
napi->constructor()(globalObject, reinterpret_cast<JSC::CallFrame*>(NAPICallFrame::toNapiCallbackInfo(frame)));
|
||||
napi->constructor()(napi->env(), NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode(frame.thisValue()));
|
||||
}
|
||||
|
||||
NapiClass* NapiClass::create(VM& vm, Zig::GlobalObject* globalObject, const char* utf8name,
|
||||
NapiClass* NapiClass::create(VM& vm, napi_env env, const char* utf8name,
|
||||
size_t length,
|
||||
napi_callback constructor,
|
||||
void* data,
|
||||
@@ -1867,8 +1866,9 @@ NapiClass* NapiClass::create(VM& vm, Zig::GlobalObject* globalObject, const char
|
||||
{
|
||||
WTF::String name = WTF::String::fromUTF8({ utf8name, length }).isolatedCopy();
|
||||
NativeExecutable* executable = vm.getHostFunction(NapiClass_ConstructorFunction, ImplementationVisibility::Public, NapiClass_ConstructorFunction, name);
|
||||
auto* globalObject = env->globalObject();
|
||||
Structure* structure = globalObject->NapiClassStructure();
|
||||
NapiClass* napiClass = new (NotNull, allocateCell<NapiClass>(vm)) NapiClass(vm, executable, globalObject, structure);
|
||||
NapiClass* napiClass = new (NotNull, allocateCell<NapiClass>(vm)) NapiClass(vm, executable, env, structure);
|
||||
napiClass->finishCreation(vm, executable, length, name, constructor, data, property_count, properties);
|
||||
return napiClass;
|
||||
}
|
||||
@@ -1880,7 +1880,7 @@ void NapiClass::finishCreation(VM& vm, NativeExecutable* executable, unsigned le
|
||||
{
|
||||
Base::finishCreation(vm, executable, length, name);
|
||||
ASSERT(inherits(info()));
|
||||
this->m_constructor = reinterpret_cast<CFFIFunction>(constructor);
|
||||
this->m_constructor = constructor;
|
||||
auto globalObject = reinterpret_cast<Zig::GlobalObject*>(this->globalObject());
|
||||
|
||||
this->putDirect(vm, vm.propertyNames->name, jsString(vm, name), JSC::PropertyAttribute::DontEnum | 0);
|
||||
@@ -1893,9 +1893,9 @@ void NapiClass::finishCreation(VM& vm, NativeExecutable* executable, unsigned le
|
||||
const napi_property_descriptor& property = properties[i];
|
||||
|
||||
if (property.attributes & napi_static) {
|
||||
defineNapiProperty(globalObject, this, nullptr, property, true, throwScope);
|
||||
defineNapiProperty(m_env, this, nullptr, property, true, throwScope);
|
||||
} else {
|
||||
defineNapiProperty(globalObject, prototype, nullptr, property, false, throwScope);
|
||||
defineNapiProperty(m_env, prototype, nullptr, property, false, throwScope);
|
||||
}
|
||||
|
||||
if (throwScope.exception())
|
||||
@@ -1929,7 +1929,7 @@ extern "C" napi_status napi_get_all_property_names(
|
||||
jsc_property_mode = PropertyNameMode::Symbols;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
|
||||
auto objectValue = toJS(objectNapi);
|
||||
auto* object = objectValue.getObject();
|
||||
@@ -1954,7 +1954,7 @@ napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto globalObject = toJS(env);
|
||||
auto globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto lastException = vm.lastException();
|
||||
if (!lastException) {
|
||||
@@ -1998,13 +1998,13 @@ extern "C" napi_status napi_define_class(napi_env env,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
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);
|
||||
NapiClass* napiClass = NapiClass::create(vm, env, utf8name, len, constructor, data, property_count, properties);
|
||||
JSC::JSValue value = JSC::JSValue(napiClass);
|
||||
JSC::EnsureStillAliveScope ensureStillAlive1(value);
|
||||
if (data != nullptr) {
|
||||
@@ -2023,7 +2023,7 @@ extern "C" napi_status napi_coerce_to_string(napi_env env, napi_value value,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
@@ -2052,7 +2052,7 @@ extern "C" napi_status napi_get_property_names(napi_env env, napi_value object,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSValue jsValue = toJS(object);
|
||||
@@ -2086,14 +2086,14 @@ extern "C" napi_status napi_create_external_buffer(napi_env env, size_t length,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(data), length }, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) {
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(data), length }, createSharedTask<void(void*)>([finalize_hint, finalize_cb, env](void* p) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] buffer finalize_callback\n");
|
||||
#endif
|
||||
if (finalize_cb != nullptr) {
|
||||
finalize_cb(toNapi(globalObject), p, finalize_hint);
|
||||
finalize_cb(env, p, finalize_hint);
|
||||
}
|
||||
}));
|
||||
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
|
||||
@@ -2113,15 +2113,15 @@ extern "C" napi_status napi_create_external_arraybuffer(napi_env env, void* exte
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(external_data), byte_length }, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) {
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(external_data), byte_length }, createSharedTask<void(void*)>([finalize_hint, finalize_cb, env](void* p) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] arraybuffer finalize_callback\n");
|
||||
#endif
|
||||
if (finalize_cb != nullptr) {
|
||||
finalize_cb(toNapi(globalObject), p, finalize_hint);
|
||||
finalize_cb(env, p, finalize_hint);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -2140,7 +2140,7 @@ extern "C" napi_status napi_create_double(napi_env env, double value,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
*result = toNapi(jsDoubleNumber(value), toJS(env));
|
||||
*result = toNapi(jsDoubleNumber(value), env->globalObject());
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -2149,7 +2149,7 @@ extern "C" napi_status napi_get_value_double(napi_env env, napi_value value,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
JSC::JSValue jsValue = toJS(value);
|
||||
|
||||
if (UNLIKELY(result == nullptr || !globalObject)) {
|
||||
@@ -2173,7 +2173,7 @@ extern "C" napi_status napi_get_value_int32(napi_env env, napi_value value, int3
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
JSC::JSValue jsValue = toJS(value);
|
||||
|
||||
if (UNLIKELY(result == nullptr || !globalObject)) {
|
||||
@@ -2197,7 +2197,7 @@ extern "C" napi_status napi_get_value_uint32(napi_env env, napi_value value, uin
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
JSC::JSValue jsValue = toJS(value);
|
||||
|
||||
if (UNLIKELY(result == nullptr || !globalObject)) {
|
||||
@@ -2221,7 +2221,7 @@ extern "C" napi_status napi_get_value_int64(napi_env env, napi_value value, int6
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
auto* globalObject = env->globalObject();
|
||||
JSC::JSValue jsValue = toJS(value);
|
||||
|
||||
if (UNLIKELY(result == nullptr || !globalObject)) {
|
||||
@@ -2258,7 +2258,7 @@ extern "C" napi_status napi_get_value_string_utf8(napi_env env,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
JSGlobalObject* globalObject = toJS(env);
|
||||
JSGlobalObject* globalObject = env->globalObject();
|
||||
|
||||
JSValue jsValue = toJS(napiValue);
|
||||
if (!jsValue || !jsValue.isString()) {
|
||||
@@ -2332,10 +2332,10 @@ extern "C" napi_status napi_get_element(napi_env env, napi_value objectValue,
|
||||
JSObject* object = jsValue.getObject();
|
||||
|
||||
auto scope = DECLARE_THROW_SCOPE(object->vm());
|
||||
JSValue element = object->getIndex(toJS(env), index);
|
||||
JSValue element = object->getIndex(env->globalObject(), index);
|
||||
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
|
||||
|
||||
*result = toNapi(element, toJS(env));
|
||||
*result = toNapi(element, env->globalObject());
|
||||
|
||||
return napi_ok;
|
||||
}
|
||||
@@ -2354,7 +2354,7 @@ extern "C" napi_status napi_delete_element(napi_env env, napi_value objectValue,
|
||||
|
||||
auto scope = DECLARE_THROW_SCOPE(object->vm());
|
||||
if (LIKELY(result)) {
|
||||
*result = JSObject::deletePropertyByIndex(object, toJS(env), index);
|
||||
*result = JSObject::deletePropertyByIndex(object, env->globalObject(), index);
|
||||
}
|
||||
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
|
||||
|
||||
@@ -2369,7 +2369,7 @@ extern "C" napi_status napi_create_object(napi_env env, napi_value* result)
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSValue value = JSValue(NapiPrototype::create(vm, globalObject->NapiPrototypeStructure()));
|
||||
@@ -2389,11 +2389,11 @@ extern "C" napi_status napi_create_external(napi_env env, void* data,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
auto* structure = globalObject->NapiExternalStructure();
|
||||
JSValue value = Bun::NapiExternal::create(vm, structure, data, finalize_hint, reinterpret_cast<void*>(finalize_cb));
|
||||
JSValue value = Bun::NapiExternal::create(vm, structure, data, finalize_hint, env, reinterpret_cast<void*>(finalize_cb));
|
||||
JSC::EnsureStillAliveScope ensureStillAlive(value);
|
||||
*result = toNapi(value, globalObject);
|
||||
return napi_ok;
|
||||
@@ -2550,18 +2550,16 @@ extern "C" napi_status napi_get_value_external(napi_env env, napi_value value,
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
// TODO: make this per addon instead of globally shared for ALL addons
|
||||
extern "C" napi_status napi_get_instance_data(napi_env env,
|
||||
void** data)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
if (UNLIKELY(data == nullptr)) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
*data = globalObject->napiInstanceData;
|
||||
*data = env->getInstanceData();
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -2570,7 +2568,7 @@ extern "C" napi_status napi_run_script(napi_env env, napi_value script,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
if (UNLIKELY(result == nullptr)) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
@@ -2616,13 +2614,7 @@ extern "C" napi_status napi_set_instance_data(napi_env env,
|
||||
void* finalize_hint)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
globalObject->napiInstanceData = data;
|
||||
|
||||
globalObject->napiInstanceDataFinalizer = reinterpret_cast<void*>(finalize_cb);
|
||||
globalObject->napiInstanceDataFinalizerHint = finalize_hint;
|
||||
|
||||
env->setInstanceData(data, finalize_cb, finalize_hint);
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -2638,7 +2630,7 @@ extern "C" napi_status napi_create_bigint_words(napi_env env,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto* bigint = JSC::JSBigInt::tryCreateWithLength(vm, word_count);
|
||||
if (UNLIKELY(!bigint)) {
|
||||
@@ -2666,7 +2658,7 @@ extern "C" napi_status napi_create_symbol(napi_env env, napi_value description,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
if (UNLIKELY(result == nullptr || globalObject == nullptr)) {
|
||||
@@ -2705,7 +2697,7 @@ extern "C" napi_status napi_new_instance(napi_env env, napi_value constructor,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
@@ -2738,7 +2730,7 @@ extern "C" napi_status napi_call_function(napi_env env, napi_value recv_napi,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
JSC::JSValue funcValue = toJS(func_napi);
|
||||
@@ -2784,7 +2776,7 @@ extern "C" napi_status napi_type_tag_object(napi_env env, napi_value value, cons
|
||||
if (!env || !value || !type_tag) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSObject* js_object = toJS(value).getObject();
|
||||
if (!js_object) {
|
||||
return napi_object_expected;
|
||||
@@ -2808,7 +2800,7 @@ extern "C" napi_status napi_check_object_type_tag(napi_env env, napi_value value
|
||||
if (!env || !value || !type_tag) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSObject* js_object = toJS(value).getObject();
|
||||
if (!js_object) {
|
||||
return napi_object_expected;
|
||||
@@ -2824,3 +2816,8 @@ extern "C" napi_status napi_check_object_type_tag(napi_env env, napi_value value
|
||||
}
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
extern "C" JSGlobalObject* NapiEnv__globalObject(napi_env env)
|
||||
{
|
||||
return env->globalObject();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "headers-handwritten.h"
|
||||
#include "BunClientData.h"
|
||||
#include <JavaScriptCore/CallFrame.h>
|
||||
#include "js_native_api.h"
|
||||
#include "node_api.h"
|
||||
#include <JavaScriptCore/JSWeakValue.h>
|
||||
#include "JSFFIFunction.h"
|
||||
#include "ZigGlobalObject.h"
|
||||
@@ -22,6 +22,45 @@ namespace Napi {
|
||||
JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSObject* object, JSC::JSGlobalObject* globalObject);
|
||||
}
|
||||
|
||||
struct napi_env__ {
|
||||
public:
|
||||
napi_env__(Zig::GlobalObject* globalObject, const napi_module& napiModule)
|
||||
: m_globalObject(globalObject)
|
||||
, m_napiModule(napiModule)
|
||||
{
|
||||
}
|
||||
|
||||
inline Zig::GlobalObject* globalObject() const { return m_globalObject; }
|
||||
inline const napi_module& napiModule() const { return m_napiModule; }
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
if (m_instanceDataFinalizer) {
|
||||
m_instanceDataFinalizer(this, m_instanceData, m_instanceDataFinalizerHint);
|
||||
}
|
||||
}
|
||||
|
||||
void setInstanceData(void* data, napi_finalize finalizer, void* hint)
|
||||
{
|
||||
m_instanceData = data;
|
||||
m_instanceDataFinalizer = finalizer;
|
||||
m_instanceDataFinalizerHint = hint;
|
||||
}
|
||||
|
||||
inline void* getInstanceData() const
|
||||
{
|
||||
return m_instanceData;
|
||||
}
|
||||
|
||||
private:
|
||||
Zig::GlobalObject* m_globalObject = nullptr;
|
||||
napi_module m_napiModule;
|
||||
|
||||
void* m_instanceData = nullptr;
|
||||
napi_finalize m_instanceDataFinalizer = nullptr;
|
||||
void* m_instanceDataFinalizerHint = nullptr;
|
||||
};
|
||||
|
||||
namespace Zig {
|
||||
|
||||
using namespace JSC;
|
||||
@@ -31,11 +70,6 @@ static inline JSValue toJS(napi_value val)
|
||||
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(val));
|
||||
}
|
||||
|
||||
static inline Zig::GlobalObject* toJS(napi_env val)
|
||||
{
|
||||
return reinterpret_cast<Zig::GlobalObject*>(val);
|
||||
}
|
||||
|
||||
static inline napi_value toNapi(JSC::JSValue val, Zig::GlobalObject* globalObject)
|
||||
{
|
||||
if (val.isCell()) {
|
||||
@@ -46,17 +80,12 @@ static inline napi_value toNapi(JSC::JSValue val, Zig::GlobalObject* globalObjec
|
||||
return reinterpret_cast<napi_value>(JSC::JSValue::encode(val));
|
||||
}
|
||||
|
||||
static inline napi_env toNapi(JSC::JSGlobalObject* val)
|
||||
{
|
||||
return reinterpret_cast<napi_env>(val);
|
||||
}
|
||||
|
||||
class NapiFinalizer {
|
||||
public:
|
||||
void* finalize_hint = nullptr;
|
||||
napi_finalize finalize_cb;
|
||||
|
||||
void call(JSC::JSGlobalObject* globalObject, void* data);
|
||||
void call(napi_env env, void* data);
|
||||
};
|
||||
|
||||
// This is essentially JSC::JSWeakValue, except with a JSCell* instead of a
|
||||
@@ -147,12 +176,11 @@ public:
|
||||
void unref();
|
||||
void clear();
|
||||
|
||||
NapiRef(JSC::JSGlobalObject* global, uint32_t count)
|
||||
NapiRef(napi_env env, uint32_t count)
|
||||
: env(env)
|
||||
, globalObject(JSC::Weak<JSC::JSGlobalObject>(env->globalObject()))
|
||||
, refCount(count)
|
||||
{
|
||||
globalObject = JSC::Weak<JSC::JSGlobalObject>(global);
|
||||
strongRef = {};
|
||||
weakValueRef.clear();
|
||||
refCount = count;
|
||||
}
|
||||
|
||||
JSC::JSValue value() const
|
||||
@@ -172,6 +200,7 @@ public:
|
||||
weakValueRef.clear();
|
||||
}
|
||||
|
||||
napi_env env = nullptr;
|
||||
JSC::Weak<JSC::JSGlobalObject> globalObject;
|
||||
NapiWeakValue weakValueRef;
|
||||
JSC::Strong<JSC::Unknown> strongRef;
|
||||
@@ -210,7 +239,7 @@ public:
|
||||
|
||||
DECLARE_EXPORT_INFO;
|
||||
|
||||
JS_EXPORT_PRIVATE static NapiClass* create(VM&, Zig::GlobalObject*, const char* utf8name,
|
||||
JS_EXPORT_PRIVATE static NapiClass* create(VM&, napi_env, const char* utf8name,
|
||||
size_t length,
|
||||
napi_callback constructor,
|
||||
void* data,
|
||||
@@ -223,18 +252,22 @@ public:
|
||||
return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
CFFIFunction constructor()
|
||||
napi_callback constructor()
|
||||
{
|
||||
return m_constructor;
|
||||
}
|
||||
|
||||
void* dataPtr = nullptr;
|
||||
CFFIFunction m_constructor = nullptr;
|
||||
napi_callback m_constructor = nullptr;
|
||||
NapiRef* napiRef = nullptr;
|
||||
napi_env m_env = nullptr;
|
||||
|
||||
inline napi_env env() const { return m_env; }
|
||||
|
||||
private:
|
||||
NapiClass(VM& vm, NativeExecutable* executable, JSC::JSGlobalObject* global, Structure* structure)
|
||||
: Base(vm, executable, global, structure)
|
||||
NapiClass(VM& vm, NativeExecutable* executable, napi_env env, Structure* structure)
|
||||
: Base(vm, executable, env->globalObject(), structure)
|
||||
, m_env(env)
|
||||
{
|
||||
}
|
||||
void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, napi_callback constructor,
|
||||
|
||||
@@ -5,10 +5,10 @@ namespace Bun {
|
||||
|
||||
NapiExternal::~NapiExternal()
|
||||
{
|
||||
if (finalizer) {
|
||||
if (m_finalizer) {
|
||||
// We cannot call globalObject() here because it is in a finalizer.
|
||||
// https://github.com/oven-sh/bun/issues/13001#issuecomment-2290022312
|
||||
reinterpret_cast<napi_finalize>(finalizer)(toNapi(this->napi_env), m_value, m_finalizerHint);
|
||||
reinterpret_cast<napi_finalize>(m_finalizer)(m_env, m_value, m_finalizerHint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "BunBuiltinNames.h"
|
||||
#include "BunClientData.h"
|
||||
#include "napi.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
@@ -47,11 +46,12 @@ public:
|
||||
JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
static NapiExternal* create(JSC::VM& vm, JSC::Structure* structure, void* value, void* finalizer_hint, void* finalizer)
|
||||
// env is needed only if a finalizer is passed, otherwise it may be null
|
||||
static NapiExternal* create(JSC::VM& vm, JSC::Structure* structure, void* value, void* finalizer_hint, napi_env env, void* finalizer)
|
||||
{
|
||||
NapiExternal* accessor = new (NotNull, JSC::allocateCell<NapiExternal>(vm)) NapiExternal(vm, structure);
|
||||
|
||||
accessor->finishCreation(vm, value, finalizer_hint, finalizer);
|
||||
accessor->finishCreation(vm, value, finalizer_hint, env, finalizer);
|
||||
|
||||
#if BUN_DEBUG
|
||||
if (auto* callFrame = vm.topCallFrame) {
|
||||
@@ -75,23 +75,23 @@ public:
|
||||
return accessor;
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm, void* value, void* finalizer_hint, void* finalizer)
|
||||
void finishCreation(JSC::VM& vm, void* value, void* finalizer_hint, napi_env env, void* finalizer)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
m_value = value;
|
||||
m_finalizerHint = finalizer_hint;
|
||||
napi_env = this->globalObject();
|
||||
this->finalizer = finalizer;
|
||||
m_env = env;
|
||||
m_finalizer = finalizer;
|
||||
}
|
||||
|
||||
static void destroy(JSC::JSCell* cell);
|
||||
|
||||
void* value() const { return m_value; }
|
||||
|
||||
void* m_value;
|
||||
void* m_finalizerHint;
|
||||
void* finalizer;
|
||||
JSGlobalObject* napi_env;
|
||||
void* m_value = nullptr;
|
||||
void* m_finalizerHint = nullptr;
|
||||
void* m_finalizer = nullptr;
|
||||
napi_env m_env = nullptr;
|
||||
|
||||
#if BUN_DEBUG
|
||||
String sourceOriginURL = String();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "napi_handle_scope.h"
|
||||
|
||||
#include "ZigGlobalObject.h"
|
||||
#include "napi.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
@@ -117,8 +118,8 @@ void NapiHandleScope::close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl
|
||||
}
|
||||
|
||||
NapiHandleScope::NapiHandleScope(Zig::GlobalObject* globalObject)
|
||||
: m_globalObject(globalObject)
|
||||
, m_impl(NapiHandleScope::open(globalObject, false))
|
||||
: m_impl(NapiHandleScope::open(globalObject, false))
|
||||
, m_globalObject(globalObject)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -127,19 +128,19 @@ NapiHandleScope::~NapiHandleScope()
|
||||
NapiHandleScope::close(m_globalObject, m_impl);
|
||||
}
|
||||
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(Zig::GlobalObject* globalObject, bool escapable)
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(napi_env env, bool escapable)
|
||||
{
|
||||
return NapiHandleScope::open(globalObject, escapable);
|
||||
return NapiHandleScope::open(env->globalObject(), escapable);
|
||||
}
|
||||
|
||||
extern "C" void NapiHandleScope__close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl* current)
|
||||
extern "C" void NapiHandleScope__close(napi_env env, NapiHandleScopeImpl* current)
|
||||
{
|
||||
return NapiHandleScope::close(globalObject, current);
|
||||
return NapiHandleScope::close(env->globalObject(), current);
|
||||
}
|
||||
|
||||
extern "C" void NapiHandleScope__append(Zig::GlobalObject* globalObject, JSC::EncodedJSValue value)
|
||||
extern "C" void NapiHandleScope__append(napi_env env, JSC::EncodedJSValue value)
|
||||
{
|
||||
globalObject->m_currentNapiHandleScopeImpl.get()->append(JSC::JSValue::decode(value));
|
||||
env->globalObject()->m_currentNapiHandleScopeImpl.get()->append(JSC::JSValue::decode(value));
|
||||
}
|
||||
|
||||
extern "C" bool NapiHandleScope__escape(NapiHandleScopeImpl* handleScope, JSC::EncodedJSValue value)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "BunClientData.h"
|
||||
#include "root.h"
|
||||
|
||||
typedef struct napi_env__* napi_env;
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// An array of write barriers (so that newly-added objects are not lost by GC) to JSValues. Unlike
|
||||
@@ -80,14 +82,14 @@ private:
|
||||
};
|
||||
|
||||
// Create a new handle scope in the given environment
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(Zig::GlobalObject* globalObject, bool escapable);
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(napi_env env, bool escapable);
|
||||
|
||||
// Pop the most recently created handle scope in the given environment and restore the old one.
|
||||
// Asserts that `current` is the active handle scope.
|
||||
extern "C" void NapiHandleScope__close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl* current);
|
||||
extern "C" void NapiHandleScope__close(napi_env env, NapiHandleScopeImpl* current);
|
||||
|
||||
// Store a value in the active handle scope in the given environment
|
||||
extern "C" void NapiHandleScope__append(Zig::GlobalObject* globalObject, JSC::EncodedJSValue value);
|
||||
extern "C" void NapiHandleScope__append(napi_env env, JSC::EncodedJSValue value);
|
||||
|
||||
// Put a value from the current handle scope into its escape slot reserved in the outer handle
|
||||
// scope. Returns false if the current handle scope is not escapable or if escape has already been
|
||||
|
||||
@@ -12,7 +12,7 @@ Local<External> External::New(Isolate* isolate, void* value)
|
||||
auto globalObject = isolate->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto structure = globalObject->NapiExternalStructure();
|
||||
Bun::NapiExternal* val = Bun::NapiExternal::create(vm, structure, value, nullptr, nullptr);
|
||||
Bun::NapiExternal* val = Bun::NapiExternal::create(vm, structure, value, nullptr, nullptr, nullptr);
|
||||
return isolate->currentHandleScope()->createLocal<External>(vm, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,13 +90,13 @@ private:
|
||||
void finishCreation(JSC::VM& vm);
|
||||
GlobalInternals(JSC::VM& vm, JSC::Structure* structure, Zig::GlobalObject* globalObject)
|
||||
: Base(vm, structure)
|
||||
, m_globalObject(globalObject)
|
||||
, m_currentHandleScope(nullptr)
|
||||
, m_undefinedValue(Oddball::Kind::kUndefined)
|
||||
, m_nullValue(Oddball::Kind::kNull)
|
||||
, m_trueValue(Oddball::Kind::kTrue)
|
||||
, m_falseValue(Oddball::Kind::kFalse)
|
||||
, m_isolate(this)
|
||||
, m_globalObject(globalObject)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,9 +44,9 @@ class PerformanceEntry : public RefCounted<PerformanceEntry> {
|
||||
public:
|
||||
virtual ~PerformanceEntry();
|
||||
|
||||
const String& name() const { return m_name; }
|
||||
const double startTime() const { return m_startTime; }
|
||||
const double duration() const { return m_duration; }
|
||||
inline const String& name() const { return m_name; }
|
||||
inline double startTime() const { return m_startTime; }
|
||||
inline double duration() const { return m_duration; }
|
||||
|
||||
enum class Type : uint8_t {
|
||||
Navigation = 1 << 0,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,17 @@
|
||||
"NAPI_DISABLE_CPP_EXCEPTIONS",
|
||||
"NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT=1",
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
"target_name": "second_addon",
|
||||
"sources": ["second_addon.c"],
|
||||
"include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
|
||||
"libraries": [],
|
||||
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
|
||||
"defines": [
|
||||
"NAPI_DISABLE_CPP_EXCEPTIONS",
|
||||
"NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT=1",
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1013,6 +1013,39 @@ static napi_value try_add_tag(const Napi::CallbackInfo &info) {
|
||||
return Napi::Boolean::New(env, status == napi_ok);
|
||||
}
|
||||
|
||||
// set_instance_data(number)
|
||||
static napi_value set_instance_data(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
napi_value object = info[0];
|
||||
|
||||
static int32_t data;
|
||||
assert(napi_get_value_int32(env, object, &data) == napi_ok);
|
||||
assert(napi_set_instance_data(env, &data, nullptr, nullptr) == napi_ok);
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
// get_instance_data(): number | null
|
||||
static napi_value get_instance_data(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
void *data_ptr = nullptr;
|
||||
assert(napi_get_instance_data(env, &data_ptr) == napi_ok);
|
||||
if (data_ptr == nullptr) {
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
napi_value out;
|
||||
assert(napi_create_int32(env, *(int32_t *)data_ptr, &out) == napi_ok);
|
||||
return out;
|
||||
}
|
||||
|
||||
// reset_instance_data()
|
||||
static napi_value reset_instance_data(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
assert(napi_set_instance_data(env, nullptr, nullptr, nullptr) == napi_ok);
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
Napi::Value RunCallback(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
// this function is invoked without the GC callback
|
||||
@@ -1079,6 +1112,10 @@ Napi::Object InitAll(Napi::Env env, Napi::Object exports1) {
|
||||
exports.Set("add_tag", Napi::Function::New(env, add_tag));
|
||||
exports.Set("try_add_tag", Napi::Function::New(env, try_add_tag));
|
||||
exports.Set("check_tag", Napi::Function::New(env, check_tag));
|
||||
exports.Set("set_instance_data", Napi::Function::New(env, set_instance_data));
|
||||
exports.Set("get_instance_data", Napi::Function::New(env, get_instance_data));
|
||||
exports.Set("reset_instance_data",
|
||||
Napi::Function::New(env, reset_instance_data));
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const nativeTests = require("./build/Release/napitests.node");
|
||||
const secondAddon = require("./build/Release/second_addon.node");
|
||||
|
||||
nativeTests.test_napi_class_constructor_handle_scope = () => {
|
||||
const NapiClass = nativeTests.get_class_with_constructor();
|
||||
@@ -270,4 +271,19 @@ nativeTests.test_type_tag = () => {
|
||||
console.log("o2 matches o2:", nativeTests.check_tag(o2, 3, 4));
|
||||
};
|
||||
|
||||
nativeTests.test_instance_data = () => {
|
||||
const first_data = 1337;
|
||||
const results = [];
|
||||
|
||||
results.push(nativeTests.get_instance_data() === null);
|
||||
results.push(nativeTests.set_instance_data(first_data) === undefined);
|
||||
results.push(nativeTests.get_instance_data() === first_data);
|
||||
results.push(secondAddon.get_instance_data() === 42);
|
||||
results.push(secondAddon.get_instance_data() !== nativeTests.get_instance_data());
|
||||
|
||||
console.log(results.join(" "));
|
||||
|
||||
nativeTests.reset_instance_data();
|
||||
};
|
||||
|
||||
module.exports = nativeTests;
|
||||
|
||||
46
test/napi/napi-app/second_addon.c
Normal file
46
test/napi/napi-app/second_addon.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <js_native_api.h>
|
||||
#include <node_api.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NODE_API_CALL(env, call) \
|
||||
do { \
|
||||
napi_status status = (call); \
|
||||
if (status != napi_ok) { \
|
||||
const napi_extended_error_info *error_info = NULL; \
|
||||
napi_get_last_error_info((env), &error_info); \
|
||||
const char *err_message = error_info->error_message; \
|
||||
bool is_pending; \
|
||||
napi_is_exception_pending((env), &is_pending); \
|
||||
/* If an exception is already pending, don't rethrow it */ \
|
||||
if (!is_pending) { \
|
||||
const char *message = \
|
||||
(err_message == NULL) ? "empty error message" : err_message; \
|
||||
napi_throw_error((env), NULL, message); \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static napi_value get_instance_data(napi_env env, napi_callback_info info) {
|
||||
void *data_ptr = NULL;
|
||||
NODE_API_CALL(env, napi_get_instance_data(env, &data_ptr));
|
||||
|
||||
napi_value out;
|
||||
NODE_API_CALL(env, napi_create_int32(env, *(int32_t *)data_ptr, &out));
|
||||
return out;
|
||||
}
|
||||
|
||||
/* napi_value */ NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
|
||||
napi_value get_instance_data_function;
|
||||
NODE_API_CALL(env, napi_create_function(env, "get_instance_data",
|
||||
NAPI_AUTO_LENGTH, get_instance_data,
|
||||
NULL, &get_instance_data_function));
|
||||
NODE_API_CALL(env, napi_set_named_property(env, exports, "get_instance_data",
|
||||
get_instance_data_function));
|
||||
|
||||
static int32_t instance_data = 42;
|
||||
NODE_API_CALL(env, napi_set_instance_data(env, &instance_data, NULL, NULL));
|
||||
|
||||
return exports;
|
||||
}
|
||||
@@ -319,6 +319,12 @@ describe("napi", () => {
|
||||
checkSameOutput("test_type_tag", []);
|
||||
});
|
||||
});
|
||||
|
||||
describe("instance data", () => {
|
||||
it("works with multiple envs", () => {
|
||||
checkSameOutput("test_instance_data", []);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function checkSameOutput(test: string, args: any[] | string) {
|
||||
|
||||
Reference in New Issue
Block a user