aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-05 02:05:45 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-05 02:05:45 -0700
commitc20df72d7319ff55ed4e5c9c7ff1abaab951d0bd (patch)
treec4e9489eb072f08af62ad58ee57cf04e436f6ef7
parentb8941666b46f9b7aa46e3f3db42b429a0d1d26cd (diff)
downloadbun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.tar.gz
bun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.tar.zst
bun-c20df72d7319ff55ed4e5c9c7ff1abaab951d0bd.zip
more mutexes
Former-commit-id: 52966012b4b74d24ab28a0c75740aef35fb75327
-rw-r--r--src/allocators.zig291
-rw-r--r--src/bundler.zig25
-rw-r--r--src/env_loader.zig6
-rw-r--r--src/http.zig26
-rw-r--r--src/javascript/jsc/bindings/SourceProvider.cpp38
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.cpp10
-rw-r--r--src/javascript/jsc/bindings/ZigSourceProvider.cpp9
-rw-r--r--src/javascript/jsc/bindings/ZigSourceProvider.h2
-rw-r--r--src/javascript/jsc/bindings/bindings.cpp3
-rw-r--r--src/javascript/jsc/bindings/bindings.zig17
-rw-r--r--src/javascript/jsc/bindings/headers-cpp.h2
-rw-r--r--src/javascript/jsc/bindings/headers.h4
-rw-r--r--src/javascript/jsc/bindings/headers.zig2
-rw-r--r--src/json_parser.zig23
-rw-r--r--src/runtime.version2
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