diff options
author | 2021-09-05 02:05:45 -0700 | |
---|---|---|
committer | 2021-09-05 02:05:45 -0700 | |
commit | c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd (patch) | |
tree | c4e9489eb072f08af62ad58ee57cf04e436f6ef7 | |
parent | b8941666b46f9b7aa46e3f3db42b429a0d1d26cd (diff) | |
download | bun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.tar.gz bun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.tar.zst bun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.zip |
more mutexes
Former-commit-id: 52966012b4b74d24ab28a0c75740aef35fb75327
-rw-r--r-- | src/allocators.zig | 291 | ||||
-rw-r--r-- | src/bundler.zig | 25 | ||||
-rw-r--r-- | src/env_loader.zig | 6 | ||||
-rw-r--r-- | src/http.zig | 26 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/SourceProvider.cpp | 38 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.cpp | 10 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigSourceProvider.cpp | 9 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigSourceProvider.h | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.cpp | 3 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.zig | 17 | ||||
-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 | ||||
-rw-r--r-- | src/json_parser.zig | 23 | ||||
-rw-r--r-- | src/runtime.version | 2 |
15 files changed, 149 insertions, 311 deletions
diff --git a/src/allocators.zig b/src/allocators.zig index 4150a37c8..b29435a2d 100644 --- a/src/allocators.zig +++ b/src/allocators.zig @@ -144,14 +144,19 @@ pub fn BSSList(comptime ValueType: type, comptime _count: anytype) type { overflow_list: OverflowListType, allocator: *Allocator, + mutex: Mutex = Mutex.init(), pub var instance: Self = undefined; + pub var loaded = false; pub fn init(allocator: *std.mem.Allocator) *Self { - instance = Self{ - .allocator = allocator, - .overflow_list = OverflowListType{}, - }; + if (!loaded) { + instance = Self{ + .allocator = allocator, + .overflow_list = OverflowListType{}, + }; + loaded = true; + } return &instance; } @@ -175,6 +180,8 @@ pub fn BSSList(comptime ValueType: type, comptime _count: anytype) type { } pub fn append(self: *Self, value: ValueType) !IndexType { + self.mutex.lock(); + defer self.mutex.unlock(); var result = IndexType{ .index = std.math.maxInt(u31), .is_overflow = backing_buf_used > max_index }; if (result.is_overflow) { result.index = @intCast(u31, self.overflow_list.items.len); @@ -192,6 +199,9 @@ pub fn BSSList(comptime ValueType: type, comptime _count: anytype) type { } pub const Pair = struct { index: IndexType, value: *ValueType }; pub fn appendGet(self: *Self, value: ValueType) !Pair { + self.mutex.lock(); + defer self.mutex.unlock(); + var result = IndexType{ .index = std.math.maxInt(u31), .is_overflow = backing_buf_used > max_index }; if (result.is_overflow) { result.index = @intCast(u31, self.overflow_list.items.len); @@ -209,6 +219,9 @@ pub fn BSSList(comptime ValueType: type, comptime _count: anytype) type { } pub fn update(self: *Self, result: *IndexType, value: ValueType) !*ValueType { + self.mutex.lock(); + defer self.mutex.unlock(); + if (result.index.index == NotFound.index or result.index.index == Unassigned.index) { result.index.is_overflow = backing_buf_used > max_index; if (result.index.is_overflow) { @@ -267,7 +280,7 @@ pub fn BSSList(comptime ValueType: type, comptime _count: anytype) type { }; } -const Mutex = @import("./sync.zig").Mutex; +const Mutex = @import("./lock.zig").Lock; /// Append-only list. /// Stores an initial count in .bss section of the object file @@ -480,15 +493,21 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo index: IndexMap, overflow_list: std.ArrayListUnmanaged(ValueType), allocator: *Allocator, + mutex: Mutex = Mutex.init(), pub var instance: Self = undefined; + var loaded: bool = false; + pub fn init(allocator: *std.mem.Allocator) *Self { - instance = Self{ - .index = IndexMap{}, - .allocator = allocator, - .overflow_list = std.ArrayListUnmanaged(ValueType){}, - }; + if (!loaded) { + instance = Self{ + .index = IndexMap{}, + .allocator = allocator, + .overflow_list = std.ArrayListUnmanaged(ValueType){}, + }; + loaded = true; + } return &instance; } @@ -500,6 +519,9 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo pub fn getOrPut(self: *Self, denormalized_key: []const u8) !Result { const key = if (comptime remove_trailing_slashes) std.mem.trimRight(u8, denormalized_key, "/") else denormalized_key; const _key = Wyhash.hash(Seed, key); + + self.mutex.lock(); + defer self.mutex.unlock(); var index = try self.index.getOrPut(self.allocator, _key); if (index.found_existing) { @@ -522,14 +544,19 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo }; } - pub fn get(self: *const Self, denormalized_key: []const u8) ?*ValueType { + pub fn get(self: *Self, denormalized_key: []const u8) ?*ValueType { const key = if (comptime remove_trailing_slashes) std.mem.trimRight(u8, denormalized_key, "/") else denormalized_key; const _key = Wyhash.hash(Seed, key); + self.mutex.lock(); + defer self.mutex.unlock(); const index = self.index.get(_key) orelse return null; return self.atIndex(index); } pub fn markNotFound(self: *Self, result: Result) void { + self.mutex.lock(); + defer self.mutex.unlock(); + self.index.put(self.allocator, result.hash, NotFound) catch unreachable; } @@ -544,6 +571,9 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo } pub fn put(self: *Self, result: *Result, value: ValueType) !*ValueType { + self.mutex.lock(); + defer self.mutex.unlock(); + if (result.index.index == NotFound.index or result.index.index == Unassigned.index) { result.index.is_overflow = backing_buf_used > max_index; if (result.index.is_overflow) { @@ -576,6 +606,9 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo } pub fn remove(self: *Self, denormalized_key: []const u8) void { + self.mutex.lock(); + defer self.mutex.unlock(); + const key = if (comptime remove_trailing_slashes) std.mem.trimRight(u8, denormalized_key, "/") else denormalized_key; const _key = Wyhash.hash(Seed, key); @@ -671,6 +704,8 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo // 1. Storing the underyling string. // 2. Making the key accessible at the index. pub fn putKey(self: *Self, key: anytype, result: *Result) !void { + self.map.mutex.lock(); + defer self.map.mutex.unlock(); var slice: []u8 = undefined; // Is this actually a slice into the map? Don't free it. @@ -715,240 +750,6 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, store_keys: boo }; } -pub fn TBSSMap(comptime ValueType: type, comptime count: anytype, store_keys: bool, estimated_key_length: usize) type { - const max_index = count - 1; - const BSSMapType = struct { - pub threadlocal var backing_buf: [count]ValueType = undefined; - pub threadlocal var backing_buf_used: u16 = 0; - const Allocator = std.mem.Allocator; - const Self = @This(); - - index: IndexMap, - overflow_list: std.ArrayListUnmanaged(ValueType), - allocator: *Allocator, - - pub threadlocal var instance: Self = undefined; - - pub fn init(allocator: *std.mem.Allocator) *Self { - instance = Self{ - .index = IndexMap{}, - .allocator = allocator, - .overflow_list = std.ArrayListUnmanaged(ValueType){}, - }; - - return &instance; - } - - pub fn isOverflowing() bool { - return backing_buf_used >= @as(u16, count); - } - - pub fn getOrPut(self: *Self, key: []const u8) !Result { - const _key = Wyhash.hash(Seed, key); - var index = try self.index.getOrPut(self.allocator, _key); - - if (index.found_existing) { - return Result{ - .hash = _key, - .index = index.value_ptr.*, - .status = switch (index.value_ptr.index) { - NotFound.index => .not_found, - Unassigned.index => .unknown, - else => .exists, - }, - }; - } - index.value_ptr.* = Unassigned; - - return Result{ - .hash = _key, - .index = Unassigned, - .status = .unknown, - }; - } - - pub fn get(self: *const Self, key: []const u8) ?*ValueType { - const _key = Wyhash.hash(Seed, key); - const index = self.index.get(_key) orelse return null; - return self.atIndex(index); - } - - pub fn markNotFound(self: *Self, result: Result) void { - self.index.put(self.allocator, result.hash, NotFound) catch unreachable; - } - - pub fn atIndex(self: *const Self, index: IndexType) ?*ValueType { - if (index.index == NotFound.index or index.index == Unassigned.index) return null; - - if (index.is_overflow) { - return &self.overflow_list.items[index.index]; - } else { - return &backing_buf[index.index]; - } - } - - pub fn put(self: *Self, result: *Result, value: ValueType) !*ValueType { - if (result.index.index == NotFound.index or result.index.index == Unassigned.index) { - result.index.is_overflow = backing_buf_used > max_index; - if (result.index.is_overflow) { - result.index.index = @intCast(u31, self.overflow_list.items.len); - } else { - result.index.index = backing_buf_used; - backing_buf_used += 1; - if (backing_buf_used >= max_index) { - self.overflow_list = try @TypeOf(self.overflow_list).initCapacity(self.allocator, count); - } - } - } - - try self.index.put(self.allocator, result.hash, result.index); - - if (result.index.is_overflow) { - if (self.overflow_list.items.len == result.index.index) { - const real_index = self.overflow_list.items.len; - try self.overflow_list.append(self.allocator, value); - } else { - self.overflow_list.items[result.index.index] = value; - } - - return &self.overflow_list.items[result.index.index]; - } else { - backing_buf[result.index.index] = value; - - return &backing_buf[result.index.index]; - } - } - - pub fn remove(self: *Self, key: []const u8) IndexType { - const _key = Wyhash.hash(Seed, key); - const index = self.index.get(_key) orelse return; - defer _ = self.index.remove(_key); - - switch (index) { - NotFound.index, Unassigned.index => {}, - 0...max_index => { - // if (hasDeinit(ValueType)) { - // backing_buf[index].deinit(); - // } - backing_buf[index] = undefined; - }, - else => { - const i = index - count; - if (hasDeinit(ValueType)) { - self.overflow_list.items[i].deinit(); - } - self.overflow_list.items[index - count] = undefined; - }, - } - - return index; - } - }; - if (!store_keys) { - return BSSMapType; - } - - return struct { - map: *BSSMapType, - const Self = @This(); - pub threadlocal var instance: Self = undefined; - threadlocal var key_list_buffer: [count * estimated_key_length]u8 = undefined; - threadlocal var key_list_buffer_used: usize = 0; - threadlocal var key_list_slices: [count][]u8 = undefined; - threadlocal var key_list_overflow: std.ArrayListUnmanaged([]u8) = undefined; - - pub fn init(allocator: *std.mem.Allocator) *Self { - instance = Self{ - .map = BSSMapType.init(allocator), - }; - - return &instance; - } - - pub fn isOverflowing() bool { - return instance.map.backing_buf_used >= count; - } - pub fn getOrPut(self: *Self, key: []const u8) !Result { - return try self.map.getOrPut(key); - } - pub fn get(self: *Self, key: []const u8) ?*ValueType { - return @call(.{ .modifier = .always_inline }, BSSMapType.get, .{ self.map, key }); - } - - pub fn atIndex(self: *Self, index: IndexType) ?*ValueType { - return @call(.{ .modifier = .always_inline }, BSSMapType.atIndex, .{ self.map, index }); - } - - pub fn keyAtIndex(self: *Self, index: IndexType) ?[]const u8 { - return switch (index.index) { - Unassigned.index, NotFound.index => null, - else => { - if (!index.is_overflow) { - return key_list_slices[index.index]; - } else { - return key_list_overflow.items[index.index]; - } - }, - }; - } - - pub fn put(self: *Self, key: anytype, comptime store_key: bool, result: *Result, value: ValueType) !*ValueType { - var ptr = try self.map.put(result, value); - if (store_key) { - try self.putKey(key, result); - } - - return ptr; - } - - pub fn isKeyStaticallyAllocated(key: anytype) bool { - return isSliceInBuffer(key, &key_list_buffer); - } - - // There's two parts to this. - // 1. Storing the underyling string. - // 2. Making the key accessible at the index. - pub fn putKey(self: *Self, key: anytype, result: *Result) !void { - var slice: []u8 = undefined; - - // Is this actually a slice into the map? Don't free it. - if (isKeyStaticallyAllocated(key)) { - slice = constStrToU8(key); - } else if (key_list_buffer_used + key.len < key_list_buffer.len) { - const start = key_list_buffer_used; - key_list_buffer_used += key.len; - slice = key_list_buffer[start..key_list_buffer_used]; - std.mem.copy(u8, slice, key); - } else { - slice = try self.map.allocator.dupe(u8, key); - } - - if (!result.index.is_overflow) { - key_list_slices[result.index.index] = slice; - } else { - if (@intCast(u31, key_list_overflow.items.len) > result.index.index) { - const existing_slice = key_list_overflow.items[result.index.index]; - if (!isKeyStaticallyAllocated(existing_slice)) { - self.map.allocator.free(existing_slice); - } - key_list_overflow.items[result.index.index] = slice; - } else { - try key_list_overflow.append(self.map.allocator, slice); - } - } - } - - pub fn markNotFound(self: *Self, result: Result) void { - self.map.markNotFound(result); - } - - // For now, don't free the keys. - pub fn remove(self: *Self, key: string) IndexType { - return self.map.remove(key); - } - }; -} - pub inline fn constStrToU8(s: []const u8) []u8 { return @intToPtr([*]u8, @ptrToInt(s.ptr))[0..s.len]; } diff --git a/src/bundler.zig b/src/bundler.zig index a43d6884c..c4b296d34 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -422,10 +422,9 @@ pub fn NewBundler(cache_files: bool) type { }; worker.data.shared_buffer = try MutableString.init(generator.allocator, 0); worker.data.scan_pass_result = js_parser.ScanPassResult.init(generator.allocator); - worker.data.log = generator.log.*; + worker.data.log = generator.log; defer { - generator.log.* = worker.data.log; worker.data.deinit(generator.allocator); } @@ -442,10 +441,6 @@ pub fn NewBundler(cache_files: bool) type { } for (this.workers[0..this.workers_used]) |*worker| { - worker.data.log.appendTo(generator.log) catch {}; - } - - for (this.workers[0..this.workers_used]) |*worker| { @atomicStore(bool, &worker.quit, true, .Release); } @@ -479,7 +474,7 @@ pub fn NewBundler(cache_files: bool) type { pub const WorkerData = struct { shared_buffer: MutableString = undefined, scan_pass_result: js_parser.ScanPassResult = undefined, - log: logger.Log, + log: *logger.Log, pub fn deinit(this: *WorkerData, allocator: *std.mem.Allocator) void { this.shared_buffer.deinit(); @@ -533,12 +528,19 @@ pub fn NewBundler(cache_files: bool) type { js_ast.Stmt.Data.Store.create(this.generator.allocator); this.data = this.generator.allocator.create(WorkerData) catch unreachable; this.data.* = WorkerData{ - .log = logger.Log.init(this.generator.allocator), + .log = this.generator.allocator.create(logger.Log) catch unreachable, }; + this.data.log.* = logger.Log.init(this.generator.allocator); this.data.shared_buffer = try MutableString.init(this.generator.allocator, 0); this.data.scan_pass_result = js_parser.ScanPassResult.init(this.generator.allocator); defer { + { + this.generator.log_lock.lock(); + this.data.log.appendTo(this.generator.log) catch {}; + this.generator.log_lock.unlock(); + } + this.data.deinit(this.generator.allocator); } @@ -557,7 +559,7 @@ pub fn NewBundler(cache_files: bool) type { }; }; write_lock: Lock, - + log_lock: Lock = Lock.init(), module_list: std.ArrayList(Api.JavascriptBundledModule), package_list: std.ArrayList(Api.JavascriptBundledPackage), header_string_buffer: MutableString, @@ -1085,7 +1087,7 @@ pub fn NewBundler(cache_files: bool) type { defer scan_pass_result.reset(); defer shared_buffer.reset(); defer this.bundler.resetStore(); - var log = &worker.data.log; + var log = worker.data.log; // If we're in a node_module, build that almost normally if (is_from_node_modules) { @@ -1585,6 +1587,7 @@ pub fn NewBundler(cache_files: bool) type { pub const BuildResolveResultPair = struct { written: usize, input_fd: ?StoredFileDescriptorType, + empty: bool = false, }; pub fn buildWithResolveResult( bundler: *ThisBundler, @@ -1700,7 +1703,7 @@ pub fn NewBundler(cache_files: bool) type { }; if (result.empty) { - return BuildResolveResultPair{ .written = 0, .input_fd = result.input_fd }; + return BuildResolveResultPair{ .written = 0, .input_fd = result.input_fd, .empty = true }; } try bundler.linker.link(file_path, &result, import_path_format, false); diff --git a/src/env_loader.zig b/src/env_loader.zig index 67e76c224..19b135e94 100644 --- a/src/env_loader.zig +++ b/src/env_loader.zig @@ -701,6 +701,10 @@ test "DotEnv Loader" { \\ \\NESTED_VALUES_RESPECT_ESCAPING='\$API_KEY' \\ + \\EMPTY_SINGLE_QUOTED_VALUE_IS_EMPTY_STRING_CHARS='' + \\ + \\EMPTY_DOUBLE_QUOTED_VALUE_IS_EMPTY_STRING_CHARS="" + \\ ; const source = logger.Source.initPathString(".env", VALID_ENV); var map = Map.init(default_allocator); @@ -726,6 +730,8 @@ test "DotEnv Loader" { try expect(map.get("NO_VALUE_IS_EMPTY_STRING").?.len == 0); try expectString(map.get("IGNORING_DOESNT_BREAK_OTHER_LINES").?, "'yes'"); try expectString(map.get("LEADING_SPACE_IN_UNQUOTED_VALUE_IS_TRIMMED").?, "yes"); + try expectString(map.get("EMPTY_SINGLE_QUOTED_VALUE_IS_EMPTY_STRING_CHARS").?, "''"); + try expectString(map.get("EMPTY_DOUBLE_QUOTED_VALUE_IS_EMPTY_STRING_CHARS").?, "\"\""); } test "DotEnv Process" { diff --git a/src/http.zig b/src/http.zig index e013c7dbf..7270ca09f 100644 --- a/src/http.zig +++ b/src/http.zig @@ -1823,6 +1823,30 @@ pub const RequestContext = struct { } } } + + if (written.empty) { + switch (loader) { + .css => try ctx.sendNoContent(), + .js, .jsx, .ts, .tsx, .json => { + const buf = "export default {};"; + const strong_etag = comptime std.hash.Wyhash.hash(1, buf); + const etag_content_slice = std.fmt.bufPrintIntToSlice(strong_etag_buffer[0..49], strong_etag, 16, .upper, .{}); + ctx.appendHeader("ETag", etag_content_slice); + + if (ctx.header("If-None-Match")) |etag_header| { + if (std.mem.eql(u8, etag_content_slice, etag_header.value)) { + try ctx.sendNotModified(); + return; + } + } + defer ctx.done(); + try ctx.writeStatus(200); + try ctx.prepareToSendBody(buf.len, false); + try ctx.writeBodyBuf(buf); + }, + else => unreachable, + } + } }, .noop => { try ctx.sendNotFound(); @@ -2045,7 +2069,7 @@ pub const RequestContext = struct { ctx.url.pathWithoutAssetPrefix(ctx.bundler.options.routes.asset_prefix_path), ctx.url.extname, false, - true, + false, ); } } diff --git a/src/javascript/jsc/bindings/SourceProvider.cpp b/src/javascript/jsc/bindings/SourceProvider.cpp deleted file mode 100644 index ceea95ab9..000000000 --- a/src/javascript/jsc/bindings/SourceProvider.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "root.h" -#include <JavaScriptCore/SourceProvider.h> - -#include <wtf/Lock.h> - -namespace JSC { - -// SourceProvider::SourceProvider(const SourceOrigin&, String&& sourceURL, const TextPosition& startPosition, SourceProviderSourceType) { - -// } - - -// SourceProvider::SourceProvider(const SourceOrigin& sourceOrigin, String&& sourceURL, const TextPosition& startPosition, SourceProviderSourceType sourceType) -// : m_sourceType(sourceType) -// , m_sourceOrigin(sourceOrigin) -// , m_sourceURL(WTFMove(sourceURL)) -// , m_startPosition(startPosition) -// { -// } - -// SourceProvider::~SourceProvider() -// { -// } - -// static Lock providerIdLock; - -// void SourceProvider::getID() -// { -// Locker locker { providerIdLock }; -// if (!m_id) { -// static intptr_t nextProviderID = 0; -// m_id = ++nextProviderID; -// RELEASE_ASSERT(m_id); -// } -// } - -} // namespace JSC - diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 0d9022a30..2b95b108a 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -82,14 +82,16 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers; extern "C" JSC__JSGlobalObject *Zig__GlobalObject__create(JSClassRef *globalObjectClass, int count, void *console_client) { + JSC::Options::useSourceProviderCache() = true; + JSC::Options::useUnlinkedCodeBlockJettisoning() = false; + JSC::Options::useTopLevelAwait() = true; + JSC::Options::exposeInternalModuleLoader() = true; + std::set_terminate([]() { Zig__GlobalObject__onCrash(); }); WTF::initializeMainThread(); JSC::initialize(); // JSC::Options::useCodeCache() = false; - JSC::Options::useSourceProviderCache() = true; - JSC::Options::useUnlinkedCodeBlockJettisoning() = false; - JSC::Options::useTopLevelAwait() = true; JSC::VM &vm = JSC::VM::create(JSC::LargeHeap).leakRef(); vm.heap.acquireAccess(); @@ -288,8 +290,6 @@ extern "C" bool Zig__GlobalObject__resetModuleRegistryMap(JSC__JSGlobalObject *g obj->putDirect(globalObject->vm(), identifier, map->clone(globalObject, globalObject->vm(), globalObject->mapStructure())); - vm.codeCache()->write(vm); - vm.shrinkFootprintWhenIdle(); // vm.deleteAllLinkedCode(JSC::DeleteAllCodeEffort::DeleteAllCodeIfNotCollecting); // JSC::Heap::PreventCollectionScope(vm.heap); diff --git a/src/javascript/jsc/bindings/ZigSourceProvider.cpp b/src/javascript/jsc/bindings/ZigSourceProvider.cpp index a2cb86c39..509732307 100644 --- a/src/javascript/jsc/bindings/ZigSourceProvider.cpp +++ b/src/javascript/jsc/bindings/ZigSourceProvider.cpp @@ -1,5 +1,6 @@ #include "ZigSourceProvider.h" #include "helpers.h" +#include "root.h" #include <JavaScriptCore/BytecodeCacheError.h> #include <JavaScriptCore/CodeCache.h> @@ -39,12 +40,8 @@ Ref<SourceProvider> SourceProvider::create(ResolvedSource resolvedSource) { JSC::SourceProviderSourceType::Module)); } else { - Ref<WTF::ExternalStringImpl> stringImpl_ = WTF::ExternalStringImpl::create( - resolvedSource.source_code.ptr, resolvedSource.source_code.len, - [=](WTF::ExternalStringImpl *str, void *ptr, unsigned int len) { - // ZigString__free((const unsigned char *)ptr, len, - // allocator); - }); + Ref<WTF::ExternalStringImpl> stringImpl_ = WTF::ExternalStringImpl::createStatic( + resolvedSource.source_code.ptr, resolvedSource.source_code.len); return adoptRef(*new SourceProvider( resolvedSource, reinterpret_cast<WTF::StringImpl *>(stringImpl_.ptr()), JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(toString(resolvedSource.source_url))), diff --git a/src/javascript/jsc/bindings/ZigSourceProvider.h b/src/javascript/jsc/bindings/ZigSourceProvider.h index 41002af97..24ae82af8 100644 --- a/src/javascript/jsc/bindings/ZigSourceProvider.h +++ b/src/javascript/jsc/bindings/ZigSourceProvider.h @@ -7,7 +7,7 @@ namespace JSC { class Structure; class Identifier; class SourceCodeKey; - +class SourceProvider; } // namespace JSC #include "ZigConsoleClient.h" diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp index 2afe01617..60a1dd9a6 100644 --- a/src/javascript/jsc/bindings/bindings.cpp +++ b/src/javascript/jsc/bindings/bindings.cpp @@ -1434,6 +1434,9 @@ const WTF__StringImpl *JSC__PropertyName__uid(JSC__PropertyName *arg0) { return #pragma mark - JSC::VM +void JSC__VM__shrinkFootprint(JSC__VM *arg0) { arg0->shrinkFootprintWhenIdle(); }; +void JSC__VM__whenIdle(JSC__VM *arg0, void (*ArgFn1)()) { arg0->whenIdle(ArgFn1); }; + JSC__JSLock *JSC__VM__apiLock(JSC__VM *arg0) { return makeRefPtr((*arg0).apiLock()).leakRef(); } JSC__VM *JSC__VM__create(unsigned char HeapType0) { JSC::VM *vm = diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index 65a8bef94..66a938199 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -1555,6 +1555,21 @@ pub const VM = extern struct { return cppFn("deleteAllCode", .{ vm, global_object }); } + pub fn whenIdle( + vm: *VM, + callback: fn (...) callconv(.C) void, + ) void { + return cppFn("whenIdle", .{ vm, callback }); + } + + pub fn shrinkFootprint( + vm: *VM, + ) void { + return cppFn("shrinkFootprint", .{ + vm, + }); + } + pub fn setExecutionForbidden(vm: *VM, forbidden: bool) void { cppFn("setExecutionForbidden", .{ vm, forbidden }); } @@ -1597,7 +1612,7 @@ pub const VM = extern struct { }); } - pub const Extern = [_][]const u8{ "deleteAllCode", "apiLock", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks" }; + pub const Extern = [_][]const u8{ "deleteAllCode", "apiLock", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks", "whenIdle", "shrinkFootprint" }; }; pub const ThrowScope = extern struct { diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index 312476e25..0013a2306 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1630718473 +//-- AUTOGENERATED FILE -- 1630806668 // clang-format off #pragma once diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index 3671095cc..c135d7ed4 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1630718473 +//-- AUTOGENERATED FILE -- 1630806668 // clang-format: off #pragma once @@ -493,7 +493,9 @@ CPP_DECL void JSC__VM__drainMicrotasks(JSC__VM* arg0); CPP_DECL bool JSC__VM__executionForbidden(JSC__VM* arg0); CPP_DECL bool JSC__VM__isEntered(JSC__VM* arg0); CPP_DECL void JSC__VM__setExecutionForbidden(JSC__VM* arg0, bool arg1); +CPP_DECL void JSC__VM__shrinkFootprint(JSC__VM* arg0); CPP_DECL bool JSC__VM__throwError(JSC__VM* arg0, JSC__JSGlobalObject* arg1, JSC__ThrowScope* arg2, const unsigned char* arg3, size_t arg4); +CPP_DECL void JSC__VM__whenIdle(JSC__VM* arg0, void (* ArgFn1)()); #pragma mark - JSC::ThrowScope diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig index 98db40c44..0227a5d87 100644 --- a/src/javascript/jsc/bindings/headers.zig +++ b/src/javascript/jsc/bindings/headers.zig @@ -307,7 +307,9 @@ pub extern fn JSC__VM__drainMicrotasks(arg0: [*c]JSC__VM) void; pub extern fn JSC__VM__executionForbidden(arg0: [*c]JSC__VM) bool; pub extern fn JSC__VM__isEntered(arg0: [*c]JSC__VM) bool; pub extern fn JSC__VM__setExecutionForbidden(arg0: [*c]JSC__VM, arg1: bool) void; +pub extern fn JSC__VM__shrinkFootprint(arg0: [*c]JSC__VM) void; pub extern fn JSC__VM__throwError(arg0: [*c]JSC__VM, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]JSC__ThrowScope, arg3: [*c]const u8, arg4: usize) bool; +pub extern fn JSC__VM__whenIdle(arg0: [*c]JSC__VM, ArgFn1: ?fn (...) callconv(.C) void) void; pub extern fn JSC__ThrowScope__clearException(arg0: [*c]JSC__ThrowScope) void; pub extern fn JSC__ThrowScope__declare(arg0: [*c]JSC__VM, arg1: [*c]u8, arg2: [*c]u8, arg3: usize) bJSC__ThrowScope; pub extern fn JSC__ThrowScope__exception(arg0: [*c]JSC__ThrowScope) [*c]JSC__Exception; diff --git a/src/json_parser.zig b/src/json_parser.zig index 0704d1aaa..8f8f415f3 100644 --- a/src/json_parser.zig +++ b/src/json_parser.zig @@ -211,9 +211,32 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { const JSONParser = JSONLikeParser(js_lexer.JSONOptions{}); const TSConfigParser = JSONLikeParser(js_lexer.JSONOptions{ .allow_comments = true, .allow_trailing_commas = true }); +var empty_string = E.String{ .utf8 = "" }; +var empty_object = E.Object{}; +var empty_array = E.Array{ .items = &[_]ExprNodeIndex{} }; +var empty_string_data = Expr.Data{ .e_string = &empty_string }; +var empty_object_data = Expr.Data{ .e_object = &empty_object }; +var empty_array_data = Expr.Data{ .e_array = &empty_array }; pub fn ParseJSON(source: *const logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !Expr { var parser = try JSONParser.init(allocator, source, log); + switch (source.contents.len) { + // This is to be consisntent with how disabled JS files are handled + 0 => { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }; + }, + // This is a fast pass I guess + 2 => { + if (strings.eqlComptime(source.contents[0..1], "\"\"") or strings.eqlComptime(source.contents[0..1], "''")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_string_data }; + } else if (strings.eqlComptime(source.contents[0..1], "{}")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }; + } else if (strings.eqlComptime(source.contents[0..1], "[]")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_array_data }; + } + }, + else => {}, + } return parser.parseExpr(); } diff --git a/src/runtime.version b/src/runtime.version index 79244e522..30358191b 100644 --- a/src/runtime.version +++ b/src/runtime.version @@ -1 +1 @@ -ed96593b8e099dd5
\ No newline at end of file +913cb9780447be7d
\ No newline at end of file |