diff options
author | 2022-01-21 03:39:27 -0800 | |
---|---|---|
committer | 2022-01-21 03:39:27 -0800 | |
commit | 9a5aa95893d047db0ab6d83303e30aaf3c9908cc (patch) | |
tree | 9889bde668b538aa4a80e72a7495b3dac93f3318 | |
parent | 8d623e21b672065f0ad29c5183f56761fec37891 (diff) | |
download | bun-9a5aa95893d047db0ab6d83303e30aaf3c9908cc.tar.gz bun-9a5aa95893d047db0ab6d83303e30aaf3c9908cc.tar.zst bun-9a5aa95893d047db0ab6d83303e30aaf3c9908cc.zip |
[Bun.js] `Bun.Transpiler.transform` & `Bun.Transpiler.transformSync` APIs
-rw-r--r-- | integration/bunjs-only-snippets/transpiler.test.js | 22 | ||||
-rw-r--r-- | src/allocators/mimalloc.zig | 10 | ||||
-rw-r--r-- | src/javascript/jsc/api/transpiler.zig | 317 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigConsoleClient.cpp | 206 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.cpp | 21 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.zig | 21 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/headers-cpp.h | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/headers.h | 4 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/headers.zig | 2 |
9 files changed, 483 insertions, 122 deletions
diff --git a/integration/bunjs-only-snippets/transpiler.test.js b/integration/bunjs-only-snippets/transpiler.test.js index 2c59c10b8..0a33954c5 100644 --- a/integration/bunjs-only-snippets/transpiler.test.js +++ b/integration/bunjs-only-snippets/transpiler.test.js @@ -42,9 +42,25 @@ describe("Bun.Transpiler", () => { it("reports all export names", () => { const { imports, exports } = transpiler.scan(code); - expect(exports[0]).toBe("loader"); - expect(exports[1]).toBe("action"); - expect(exports[2]).toBe("default"); + expect(exports[0]).toBe("action"); + expect(exports[2]).toBe("loader"); + expect(exports[1]).toBe("default"); + + expect(exports).toHaveLength(3); + }); + }); + + describe("transform", () => { + it("removes types", () => { + const out = transpiler.transform(code); + expect(out.includes("ActionFunction")).toBe(false); + expect(out.includes("LoaderFunction")).toBe(false); + + const { exports } = transpiler.scan(out); + + expect(exports[0]).toBe("action"); + expect(exports[2]).toBe("loader"); + expect(exports[1]).toBe("default"); expect(exports).toHaveLength(3); }); }); diff --git a/src/allocators/mimalloc.zig b/src/allocators/mimalloc.zig index 068552917..9a30195ab 100644 --- a/src/allocators/mimalloc.zig +++ b/src/allocators/mimalloc.zig @@ -46,21 +46,25 @@ pub extern fn mi_thread_done() void; pub extern fn mi_thread_stats_print_out(out: ?mi_output_fun, arg: ?*anyopaque) void; pub extern fn mi_process_info(elapsed_msecs: *usize, user_msecs: *usize, system_msecs: *usize, current_rss: *usize, peak_rss: *usize, current_commit: *usize, peak_commit: *usize, page_faults: *usize) void; pub extern fn mi_malloc_aligned(size: usize, alignment: usize) ?*anyopaque; -pub extern fn mi_malloc_aligned_at(size: usize, alignment: usize, offset: usize) ?*anyopaque; +pub extern fn mi_malloc_aligned_at(size: usize, alignment: usize, offset: usize) ?[*]u8; pub extern fn mi_zalloc_aligned(size: usize, alignment: usize) ?*anyopaque; pub extern fn mi_zalloc_aligned_at(size: usize, alignment: usize, offset: usize) ?*anyopaque; pub extern fn mi_calloc_aligned(count: usize, size: usize, alignment: usize) ?*anyopaque; pub extern fn mi_calloc_aligned_at(count: usize, size: usize, alignment: usize, offset: usize) ?*anyopaque; pub extern fn mi_realloc_aligned(p: ?*anyopaque, newsize: usize, alignment: usize) ?*anyopaque; pub extern fn mi_realloc_aligned_at(p: ?*anyopaque, newsize: usize, alignment: usize, offset: usize) ?*anyopaque; -pub const struct_mi_heap_s = opaque {}; +pub const struct_mi_heap_s = opaque { + pub inline fn backing(_: anytype) *mi_heap_t { + return mi_heap_get_backing(); + } +}; pub const mi_heap_t = struct_mi_heap_s; pub extern fn mi_heap_new() ?*mi_heap_t; pub extern fn mi_heap_delete(heap: ?*mi_heap_t) void; pub extern fn mi_heap_destroy(heap: ?*mi_heap_t) void; pub extern fn mi_heap_set_default(heap: ?*mi_heap_t) ?*mi_heap_t; pub extern fn mi_heap_get_default() ?*mi_heap_t; -pub extern fn mi_heap_get_backing() ?*mi_heap_t; +pub extern fn mi_heap_get_backing() *mi_heap_t; pub extern fn mi_heap_collect(heap: ?*mi_heap_t, force: bool) void; pub extern fn mi_heap_malloc(heap: ?*mi_heap_t, size: usize) ?*anyopaque; pub extern fn mi_heap_zalloc(heap: ?*mi_heap_t, size: usize) ?*anyopaque; diff --git a/src/javascript/jsc/api/transpiler.zig b/src/javascript/jsc/api/transpiler.zig index 21209bc69..cdc5dc39a 100644 --- a/src/javascript/jsc/api/transpiler.zig +++ b/src/javascript/jsc/api/transpiler.zig @@ -37,12 +37,14 @@ const Platform = options.Platform; const JSAst = @import("../../../js_ast.zig"); const Transpiler = @This(); const JSParser = @import("../../../js_parser.zig"); +const JSPrinter = @import("../../../js_printer.zig"); const ScanPassResult = JSParser.ScanPassResult; bundler: Bundler.Bundler, arena: std.heap.ArenaAllocator, transpiler_options: TranspilerOptions, scan_pass_result: ScanPassResult, +buffer_writer: ?JSPrinter.BufferWriter = null, pub const Class = NewClass( Transpiler, @@ -54,6 +56,12 @@ pub const Class = NewClass( .scan = .{ .rfn = scan, }, + .transform = .{ + .rfn = transform, + }, + .transformSync = .{ + .rfn = transformSync, + }, .finalize = finalize, }, .{}, @@ -85,6 +93,178 @@ const TranspilerOptions = struct { tsconfig_buf: []const u8 = "", macros_buf: []const u8 = "", log: logger.Log, + pending_tasks: u32 = 0, +}; + +// Mimalloc gets unstable if we try to move this to a different thread +// threadlocal var transform_buffer: _global.MutableString = undefined; +// threadlocal var transform_buffer_loaded: bool = false; + +// This is going to be hard to not leak +pub const TransformTask = struct { + input_code: ZigString = ZigString.init(""), + protected_input_value: JSC.JSValue = @intToEnum(JSC.JSValue, 0), + output_code: ZigString = ZigString.init(""), + bundler: Bundler.Bundler = undefined, + log: logger.Log, + err: ?anyerror = null, + macro_map: MacroMap = MacroMap{}, + tsconfig: ?*TSConfigJSON = null, + loader: Loader, + global: *JSGlobalObject, + + pub const AsyncTransformTask = JSC.ConcurrentPromiseTask(TransformTask); + pub const AsyncTransformEventLoopTask = AsyncTransformTask.EventLoopTask; + + pub fn create(transpiler: *Transpiler, protected_input_value: JSC.C.JSValueRef, globalThis: *JSGlobalObject, input_code: ZigString, loader: Loader) !*AsyncTransformTask { + var transform_task = try _global.default_allocator.create(TransformTask); + transform_task.* = .{ + .input_code = input_code, + .protected_input_value = if (protected_input_value != null) JSC.JSValue.fromRef(protected_input_value) else @intToEnum(JSC.JSValue, 0), + .bundler = undefined, + .global = globalThis, + .macro_map = transpiler.transpiler_options.macro_map, + .tsconfig = transpiler.transpiler_options.tsconfig, + .log = logger.Log.init(_global.default_allocator), + .loader = loader, + }; + transform_task.bundler = transpiler.bundler; + transform_task.bundler.linker.resolver = &transform_task.bundler.resolver; + + transform_task.bundler.setLog(&transform_task.log); + transform_task.bundler.setAllocator(_global.default_allocator); + return try AsyncTransformTask.createOnJSThread(_global.default_allocator, globalThis, transform_task); + } + + pub fn run(this: *TransformTask) void { + const name = this.loader.stdinName(); + const source = logger.Source.initPathString(name, this.input_code.slice()); + const Mimalloc = @import("../../../mimalloc_arena.zig"); + + JSAst.Stmt.Data.Store.create(_global.default_allocator); + JSAst.Expr.Data.Store.create(_global.default_allocator); + + var arena = Mimalloc.Arena.init() catch unreachable; + + const allocator = arena.allocator(); + + defer { + JSAst.Stmt.Data.Store.reset(); + JSAst.Expr.Data.Store.reset(); + arena.deinit(); + } + + this.bundler.setAllocator(allocator); + const jsx = if (this.tsconfig != null) + this.tsconfig.?.mergeJSX(this.bundler.options.jsx) + else + this.bundler.options.jsx; + + const parse_options = Bundler.Bundler.ParseOptions{ + .allocator = allocator, + .macro_remappings = this.macro_map, + .dirname_fd = 0, + .file_descriptor = null, + .loader = this.loader, + .jsx = jsx, + .path = source.path, + .virtual_source = &source, + // .allocator = this. + }; + + const parse_result = this.bundler.parse(parse_options, null) orelse { + this.err = error.ParseError; + return; + }; + defer { + if (parse_result.ast.symbol_pool) |pool| { + pool.release(); + } + } + if (parse_result.empty) { + this.output_code = ZigString.init(""); + return; + } + + var global_allocator = arena.backingAllocator(); + var buffer_writer = JSPrinter.BufferWriter.init(global_allocator) catch |err| { + this.err = err; + return; + }; + // defer { + // transform_buffer = buffer_writer.buffer; + // } + + var printer = JSPrinter.BufferPrinter.init(buffer_writer); + const printed = this.bundler.print(parse_result, @TypeOf(&printer), &printer, .esm_ascii) catch |err| { + this.err = err; + return; + }; + + if (printed > 0) { + buffer_writer = printer.ctx; + buffer_writer.buffer.list.expandToCapacity(); + + // This works around a mimalloc and/or Zig allocator bug + buffer_writer.buffer.list.items = buffer_writer.buffer.list.items[0..printed]; + var output_code = JSC.ZigString.init(buffer_writer.buffer.toOwnedSlice()); + output_code.mark(); + this.output_code = output_code; + } else { + this.output_code = ZigString.init(""); + } + } + + pub fn then(this: *TransformTask, promise: *JSC.JSInternalPromise) void { + if (this.log.hasAny() or this.err != null) { + const error_value: JSValue = brk: { + if (this.err) |err| { + if (!this.log.hasAny()) { + break :brk JSC.JSValue.fromRef(JSC.BuildError.create( + this.global, + _global.default_allocator, + logger.Msg{ + .data = logger.Data{ .text = std.mem.span(@errorName(err)) }, + }, + )); + } + } + + break :brk this.log.toJS(this.global, _global.default_allocator, "Transform failed"); + }; + + promise.reject(this.global, error_value); + return; + } + + finish(this.output_code, this.global, promise); + + if (@enumToInt(this.protected_input_value) != 0) { + this.protected_input_value = @intToEnum(JSC.JSValue, 0); + } + this.deinit(); + } + + noinline fn finish(code: ZigString, global: *JSGlobalObject, promise: *JSC.JSInternalPromise) void { + promise.resolve(global, code.toValueGC(global)); + } + + pub fn deinit(this: *TransformTask) void { + var should_cleanup = false; + defer if (should_cleanup) _global.Global.mimalloc_cleanup(false); + + this.log.deinit(); + if (this.input_code.isGloballyAllocated()) { + this.input_code.deinitGlobal(); + } + + if (this.output_code.isGloballyAllocated()) { + should_cleanup = this.output_code.len > 512_000; + this.output_code.deinitGlobal(); + } + + _global.default_allocator.destroy(this); + } }; fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allocator, args: *JSC.Node.ArgumentsSlice, exception: JSC.C.ExceptionRef) TranspilerOptions { @@ -372,6 +552,9 @@ pub fn finalize( this.scan_pass_result.named_imports.deinit(); this.scan_pass_result.import_records.deinit(); this.scan_pass_result.used_symbols.deinit(); + if (this.buffer_writer != null) { + this.buffer_writer.?.buffer.deinit(); + } // _global.default_allocator.free(this.transpiler_options.tsconfig_buf); // _global.default_allocator.free(this.transpiler_options.macros_buf); @@ -477,6 +660,140 @@ pub fn scan( return JSC.JSValue.createObject2(ctx.ptr(), &imports_label, &exports_label, named_imports_value, named_exports_value).asObjectRef(); } +// pub fn build( +// this: *Transpiler, +// ctx: js.JSContextRef, +// _: js.JSObjectRef, +// _: js.JSObjectRef, +// arguments: []const js.JSValueRef, +// exception: js.ExceptionRef, +// ) JSC.C.JSObjectRef {} + +pub fn transform( + this: *Transpiler, + ctx: js.JSContextRef, + _: js.JSObjectRef, + _: js.JSObjectRef, + arguments: []const js.JSValueRef, + exception: js.ExceptionRef, +) JSC.C.JSObjectRef { + var args = JSC.Node.ArgumentsSlice.init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]); + defer args.arena.deinit(); + const code_arg = args.next() orelse { + JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception); + return null; + }; + + const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), code_arg, exception) orelse { + if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception); + return null; + }; + + const code = code_holder.slice(); + args.eat(); + const loader: ?Loader = brk: { + if (args.next()) |arg| { + args.eat(); + break :brk Loader.fromJS(ctx.ptr(), arg, exception); + } + + break :brk null; + }; + + if (exception.* != null) return null; + if (code_holder == .string) { + JSC.C.JSValueProtect(ctx, arguments[0]); + } + + var task = TransformTask.create(this, if (code_holder == .string) arguments[0] else null, ctx.ptr(), ZigString.init(code), loader orelse this.transpiler_options.default_loader) catch return null; + task.schedule(); + return task.promise.asObjectRef(); +} + +pub fn transformSync( + this: *Transpiler, + ctx: js.JSContextRef, + _: js.JSObjectRef, + _: js.JSObjectRef, + arguments: []const js.JSValueRef, + exception: js.ExceptionRef, +) JSC.C.JSObjectRef { + var args = JSC.Node.ArgumentsSlice.init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]); + defer args.arena.deinit(); + const code_arg = args.next() orelse { + JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception); + return null; + }; + + const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), code_arg, exception) orelse { + if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception); + return null; + }; + + const code = code_holder.slice(); + args.eat(); + const loader: ?Loader = brk: { + if (args.next()) |arg| { + args.eat(); + break :brk Loader.fromJS(ctx.ptr(), arg, exception); + } + + break :brk null; + }; + + if (exception.* != null) return null; + + defer { + JSAst.Stmt.Data.Store.reset(); + JSAst.Expr.Data.Store.reset(); + } + + const parse_result = getParseResult(this, args.arena.allocator(), code, loader) orelse { + if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) { + var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error"); + exception.* = out_exception.asObjectRef(); + return null; + } + + JSC.throwInvalidArguments("Failed to parse", .{}, ctx, exception); + return null; + }; + defer { + if (parse_result.ast.symbol_pool) |symbols| { + symbols.release(); + } + } + + if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) { + var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error"); + exception.* = out_exception.asObjectRef(); + return null; + } + if (this.buffer_writer == null) { + this.buffer_writer = JSPrinter.BufferWriter.init(_global.default_allocator) catch { + JSC.throwInvalidArguments("Failed to create BufferWriter", .{}, ctx, exception); + return null; + }; + this.buffer_writer.?.buffer.growIfNeeded(code.len) catch unreachable; + this.buffer_writer.?.buffer.list.expandToCapacity(); + } + + this.buffer_writer.?.reset(); + var printer = JSPrinter.BufferPrinter.init(this.buffer_writer.?); + const printed = this.bundler.print(parse_result, @TypeOf(printer), printer, .esm_ascii) catch |err| { + JSC.JSError(_global.default_allocator, "Failed to print code: {s}", .{@errorName(err)}, ctx, exception); + return null; + }; + + // TODO: benchmark if pooling this way is faster or moving is faster + this.buffer_writer = printer.ctx; + this.buffer_writer.?.buffer.list.expandToCapacity(); + var out = JSC.ZigString.init(this.buffer_writer.?.buffer.list.items[0..printed]); + out.mark(); + + return out.toValueGC(ctx.ptr()).asObjectRef(); +} + fn namedExportsToJS(global: *JSGlobalObject, named_exports: JSAst.Ast.NamedExports) JSC.JSValue { if (named_exports.count() == 0) return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArray(global.ref(), 0, null, null)); diff --git a/src/javascript/jsc/bindings/ZigConsoleClient.cpp b/src/javascript/jsc/bindings/ZigConsoleClient.cpp index b88bb8064..9e7bf7d3f 100644 --- a/src/javascript/jsc/bindings/ZigConsoleClient.cpp +++ b/src/javascript/jsc/bindings/ZigConsoleClient.cpp @@ -3,10 +3,9 @@ #include "ZigConsoleClient.h" #include <JavaScriptCore/ConsoleClient.h> #include <JavaScriptCore/ConsoleMessage.h> +#include <JavaScriptCore/JSString.h> #include <JavaScriptCore/ScriptArguments.h> #include <wtf/text/WTFString.h> -#include <JavaScriptCore/JSString.h> - using ScriptArguments = Inspector::ScriptArguments; using MessageType = JSC::MessageType; using MessageLevel = JSC::MessageLevel; @@ -14,124 +13,111 @@ using JSGlobalObject = JSC__JSGlobalObject; using String = WTF::String; -extern "C" { -JSC__JSValue Inspector__ScriptArguments__argumentAt( Inspector__ScriptArguments* arg0, size_t i) { -return JSC::JSValue::encode(arg0->argumentAt(i)); -} -size_t Inspector__ScriptArguments__argumentCount( Inspector__ScriptArguments* arg0) { - return arg0->argumentCount(); -} -bWTF__String Inspector__ScriptArguments__getFirstArgumentAsString( Inspector__ScriptArguments* arg0) { - auto scope = DECLARE_CATCH_SCOPE(arg0->globalObject()->vm()); - JSC::JSValue val0 = arg0->argumentAt(0); - auto type = val0.asCell()->type(); - Wrap<WTF::String, bWTF__String> wrap; - wrap.cpp = new (wrap.alignedBuffer()) WTF::String(val0.getString(arg0->globalObject()) ); - scope.clearException(); - return wrap.result; -} +namespace JSC { -bool Inspector__ScriptArguments__isEqual( Inspector__ScriptArguments* arg0, Inspector__ScriptArguments* arg1) { - return arg0->isEqual(*arg1); -} +ALWAYS_INLINE GCDeferralContext::GCDeferralContext(Heap &heap) : m_heap(heap) {} -void Inspector__ScriptArguments__release(Inspector__ScriptArguments* arg0) { - auto count = arg0->argumentCount(); - for (int i = 0; i < count; i++) { - JSC::gcUnprotect(arg0->argumentAt(i)); - } - arg0->deref(); -} +ALWAYS_INLINE GCDeferralContext::~GCDeferralContext() { + if constexpr (validateDFGDoesGC) m_heap.verifyCanGC(); + if (UNLIKELY(m_shouldGC)) m_heap.collectIfNecessaryOrDefer(); } -void Zig::ConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments) { - // JSC::JSLockHolder holder(arguments->globalObject()->vm()); - - auto args = arguments.ptr(); - JSC__JSValue jsArgs[255]; - auto count = std::min(args->argumentCount(), (size_t)255); - for (size_t i = 0; i < count; i++) { - auto val = args->argumentAt(i); - // JSC::gcProtect(val); - jsArgs[i] = JSC::JSValue::encode(val); - - } - - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); - Zig__ConsoleClient__messageWithTypeAndLevel( - this->m_client, - static_cast<uint32_t>(type), - static_cast<uint32_t>(level), - globalObject, - jsArgs, - count - ); - scope.clearException(); - - // for (size_t i = 0; i < count; i++) { - // JSC::gcUnprotect(JSC::JSValue::decode(jsArgs[i])); - // } +} // namespace JSC +extern "C" { +JSC__JSValue Inspector__ScriptArguments__argumentAt(Inspector__ScriptArguments *arg0, size_t i) { + return JSC::JSValue::encode(arg0->argumentAt(i)); +} +size_t Inspector__ScriptArguments__argumentCount(Inspector__ScriptArguments *arg0) { + return arg0->argumentCount(); +} +bWTF__String +Inspector__ScriptArguments__getFirstArgumentAsString(Inspector__ScriptArguments *arg0) { + auto scope = DECLARE_CATCH_SCOPE(arg0->globalObject()->vm()); + JSC::JSValue val0 = arg0->argumentAt(0); + auto type = val0.asCell()->type(); + Wrap<WTF::String, bWTF__String> wrap; + wrap.cpp = new (wrap.alignedBuffer()) WTF::String(val0.getString(arg0->globalObject())); + scope.clearException(); + return wrap.result; } -void Zig::ConsoleClient::count(JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__count(this->m_client, globalObject, ptr, label.length()); + +bool Inspector__ScriptArguments__isEqual(Inspector__ScriptArguments *arg0, + Inspector__ScriptArguments *arg1) { + return arg0->isEqual(*arg1); } -void Zig::ConsoleClient::countReset(JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__countReset(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::profile(JSC::JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__profile(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::profileEnd(JSC::JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__profileEnd(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::takeHeapSnapshot(JSC::JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__takeHeapSnapshot(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::time(JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__time(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::timeLog(JSGlobalObject* globalObject, const String& label, Ref<ScriptArguments>&& arguments) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__timeLog(this->m_client, globalObject, ptr, label.length(), arguments.ptr()); -} -void Zig::ConsoleClient::timeEnd(JSGlobalObject* globalObject, const String& label) -{ - auto ptr = label.characters8(); - Zig__ConsoleClient__timeEnd(this->m_client, globalObject, ptr, label.length()); -} -void Zig::ConsoleClient::timeStamp(JSGlobalObject* globalObject, Ref<ScriptArguments>&& args) -{ - Zig__ConsoleClient__timeStamp(this->m_client, globalObject, args.ptr()); -} -void Zig::ConsoleClient::record(JSGlobalObject*, Ref<ScriptArguments>&&) -{ - -} -void Zig::ConsoleClient::recordEnd(JSGlobalObject*, Ref<ScriptArguments>&&) -{ +void Inspector__ScriptArguments__release(Inspector__ScriptArguments *arg0) { + auto count = arg0->argumentCount(); + for (int i = 0; i < count; i++) { JSC::gcUnprotect(arg0->argumentAt(i)); } + arg0->deref(); +} +} +void Zig::ConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, + JSC::JSGlobalObject *globalObject, + Ref<ScriptArguments> &&arguments) { + JSC::VM &vm = globalObject->vm(); + JSC::GCDeferralContext deferralContext(vm.heap); + JSC::DisallowGC disallowGC; + auto args = arguments.ptr(); + JSC__JSValue jsArgs[255]; + + auto count = std::min(args->argumentCount(), (size_t)255); + for (size_t i = 0; i < count; i++) { + auto val = args->argumentAt(i); + // JSC::gcProtect(val); + jsArgs[i] = JSC::JSValue::encode(val); + } + + auto scope = DECLARE_THROW_SCOPE(vm); + Zig__ConsoleClient__messageWithTypeAndLevel(this->m_client, static_cast<uint32_t>(type), + static_cast<uint32_t>(level), globalObject, jsArgs, + count); + scope.clearException(); + // for (size_t i = 0; i < count; i++) { + // JSC::gcUnprotect(JSC::JSValue::decode(jsArgs[i])); + // } } -void Zig::ConsoleClient::screenshot(JSGlobalObject*, Ref<ScriptArguments>&&) -{ - +void Zig::ConsoleClient::count(JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__count(this->m_client, globalObject, ptr, label.length()); } -void Zig::ConsoleClient::warnUnimplemented(const String& method) -{ -}
\ No newline at end of file +void Zig::ConsoleClient::countReset(JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__countReset(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::profile(JSC::JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__profile(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::profileEnd(JSC::JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__profileEnd(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::takeHeapSnapshot(JSC::JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__takeHeapSnapshot(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::time(JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__time(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::timeLog(JSGlobalObject *globalObject, const String &label, + Ref<ScriptArguments> &&arguments) { + auto ptr = label.characters8(); + Zig__ConsoleClient__timeLog(this->m_client, globalObject, ptr, label.length(), arguments.ptr()); +} +void Zig::ConsoleClient::timeEnd(JSGlobalObject *globalObject, const String &label) { + auto ptr = label.characters8(); + Zig__ConsoleClient__timeEnd(this->m_client, globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::timeStamp(JSGlobalObject *globalObject, Ref<ScriptArguments> &&args) { + Zig__ConsoleClient__timeStamp(this->m_client, globalObject, args.ptr()); +} +void Zig::ConsoleClient::record(JSGlobalObject *, Ref<ScriptArguments> &&) {} +void Zig::ConsoleClient::recordEnd(JSGlobalObject *, Ref<ScriptArguments> &&) {} +void Zig::ConsoleClient::screenshot(JSGlobalObject *, Ref<ScriptArguments> &&) {} +void Zig::ConsoleClient::warnUnimplemented(const String &method) {}
\ No newline at end of file diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp index c73cb8099..492a65fda 100644 --- a/src/javascript/jsc/bindings/bindings.cpp +++ b/src/javascript/jsc/bindings/bindings.cpp @@ -209,6 +209,16 @@ void JSC__JSValue__putRecord(JSC__JSValue objectValue, JSC__JSGlobalObject *glob scope.release(); } +JSC__JSInternalPromise *JSC__JSValue__asInternalPromise(JSC__JSValue JSValue0) { + JSC::JSValue value = JSC::JSValue::decode(JSValue0); + return JSC::jsCast<JSC::JSInternalPromise *>(value); +} +JSC__JSValue JSC__JSValue__createInternalPromise(JSC__JSGlobalObject *globalObject) { + JSC::VM &vm = globalObject->vm(); + return JSC::JSValue::encode( + JSC::JSValue(JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure()))); +} + void JSC__JSValue__jsonStringify(JSC__JSValue JSValue0, JSC__JSGlobalObject *arg1, uint32_t arg2, ZigString *arg3) { JSC::JSValue value = JSC::JSValue::decode(JSValue0); @@ -656,13 +666,20 @@ JSC__JSValue ZigString__to16BitValue(const ZigString *arg0, JSC__JSGlobalObject } JSC__JSValue ZigString__toValueGC(const ZigString *arg0, JSC__JSGlobalObject *arg1) { - return JSC::JSValue::encode( - JSC::JSValue(JSC::jsMakeNontrivialString(arg1->vm(), Zig::toStringCopy(*arg0)))); + return JSC::JSValue::encode(JSC::JSValue(JSC::jsString(arg1->vm(), Zig::toStringCopy(*arg0)))); } void JSC__JSValue__toZigString(JSC__JSValue JSValue0, ZigString *arg1, JSC__JSGlobalObject *arg2) { JSC::JSValue value = JSC::JSValue::decode(JSValue0); + + // if (!value.isString()) { + // arg1->len = 0; + // arg1->ptr = nullptr; + // return; + // } + auto str = value.toWTFString(arg2); + if (str.is8Bit()) { arg1->ptr = str.characters8(); } else { diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index 77f2bc20c..f7b270a40 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -136,10 +136,14 @@ pub const ZigString = extern struct { } } - pub inline fn isGloballyAllocated(this: *ZigString) bool { + pub inline fn isGloballyAllocated(this: ZigString) bool { return (@ptrToInt(this.ptr) & (1 << 62)) != 0; } + pub inline fn deinitGlobal(this: ZigString) void { + _global.default_allocator.free(this.slice()); + } + pub inline fn mark(this: *ZigString) void { this.ptr = @intToPtr([*]const u8, @ptrToInt(this.ptr) | (1 << 62)); } @@ -1497,6 +1501,7 @@ pub const JSValue = enum(i64) { u16 => toU16(this), c_uint => @intCast(c_uint, toU32(this)), c_int => @intCast(c_int, toInt32(this)), + ?*JSInternalPromise => asInternalPromise(this), // TODO: BigUint64? u64 => @as(u64, toU32(this)), @@ -1555,6 +1560,18 @@ pub const JSValue = enum(i64) { }; } + pub fn createInternalPromise(globalObject: *JSGlobalObject) JSValue { + return cppFn("createInternalPromise", .{globalObject}); + } + + pub fn asInternalPromise( + value: JSValue, + ) ?*JSInternalPromise { + return cppFn("asInternalPromise", .{ + value, + }); + } + pub fn jsNumber(number: anytype) JSValue { return jsNumberWithType(@TypeOf(number), number); } @@ -1883,7 +1900,7 @@ pub const JSValue = enum(i64) { return @intToPtr(*anyopaque, @bitCast(u64, @enumToInt(this))); } - pub const Extern = [_][]const u8{ "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" }; + pub const Extern = [_][]const u8{ "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" }; }; extern "c" fn Microtask__run(*Microtask, *JSGlobalObject) void; diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index 4ea2d08a9..2ba13ed1d 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1642723405 +//-- AUTOGENERATED FILE -- 1642736709 // clang-format off #pragma once diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index 73979e4dd..31ccc29ea 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format: off -//-- AUTOGENERATED FILE -- 1642723405 +//-- AUTOGENERATED FILE -- 1642736709 #pragma once #include <stddef.h> @@ -429,10 +429,12 @@ CPP_DECL size_t WTF__String__length(WTF__String* arg0); CPP_DECL bool JSC__JSValue__asArrayBuffer_(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, Bun__ArrayBuffer* arg2); CPP_DECL JSC__JSCell* JSC__JSValue__asCell(JSC__JSValue JSValue0); +CPP_DECL JSC__JSInternalPromise* JSC__JSValue__asInternalPromise(JSC__JSValue JSValue0); CPP_DECL double JSC__JSValue__asNumber(JSC__JSValue JSValue0); CPP_DECL bJSC__JSObject JSC__JSValue__asObject(JSC__JSValue JSValue0); CPP_DECL JSC__JSString* JSC__JSValue__asString(JSC__JSValue JSValue0); CPP_DECL JSC__JSValue JSC__JSValue__createEmptyObject(JSC__JSGlobalObject* arg0, size_t arg1); +CPP_DECL JSC__JSValue JSC__JSValue__createInternalPromise(JSC__JSGlobalObject* arg0); CPP_DECL JSC__JSValue JSC__JSValue__createObject2(JSC__JSGlobalObject* arg0, const ZigString* arg1, const ZigString* arg2, JSC__JSValue JSValue3, JSC__JSValue JSValue4); CPP_DECL JSC__JSValue JSC__JSValue__createRangeError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2); CPP_DECL JSC__JSValue JSC__JSValue__createStringArray(JSC__JSGlobalObject* arg0, ZigString* arg1, size_t arg2, bool arg3); diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig index 7ce45a4cc..9b637f427 100644 --- a/src/javascript/jsc/bindings/headers.zig +++ b/src/javascript/jsc/bindings/headers.zig @@ -273,10 +273,12 @@ pub extern fn WTF__String__isStatic(arg0: [*c]WTF__String) bool; pub extern fn WTF__String__length(arg0: [*c]WTF__String) usize; pub extern fn JSC__JSValue__asArrayBuffer_(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]Bun__ArrayBuffer) bool; pub extern fn JSC__JSValue__asCell(JSValue0: JSC__JSValue) [*c]JSC__JSCell; +pub extern fn JSC__JSValue__asInternalPromise(JSValue0: JSC__JSValue) [*c]JSC__JSInternalPromise; pub extern fn JSC__JSValue__asNumber(JSValue0: JSC__JSValue) f64; pub extern fn JSC__JSValue__asObject(JSValue0: JSC__JSValue) bJSC__JSObject; pub extern fn JSC__JSValue__asString(JSValue0: JSC__JSValue) [*c]JSC__JSString; pub extern fn JSC__JSValue__createEmptyObject(arg0: [*c]JSC__JSGlobalObject, arg1: usize) JSC__JSValue; +pub extern fn JSC__JSValue__createInternalPromise(arg0: [*c]JSC__JSGlobalObject) JSC__JSValue; pub extern fn JSC__JSValue__createObject2(arg0: [*c]JSC__JSGlobalObject, arg1: [*c]const ZigString, arg2: [*c]const ZigString, JSValue3: JSC__JSValue, JSValue4: JSC__JSValue) JSC__JSValue; pub extern fn JSC__JSValue__createRangeError(arg0: [*c]const ZigString, arg1: [*c]const ZigString, arg2: [*c]JSC__JSGlobalObject) JSC__JSValue; pub extern fn JSC__JSValue__createStringArray(arg0: [*c]JSC__JSGlobalObject, arg1: [*c]ZigString, arg2: usize, arg3: bool) JSC__JSValue; |