mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
Fix crash, fix detecting node_modules, fix undefined not being simplified
Former-commit-id: 3f197d1ce0
This commit is contained in:
@@ -43,6 +43,15 @@ pub fn JSStringMap(comptime V: type) type {
|
||||
return std.HashMap(js.JSStringRef, V, JSStringMapContext, 60);
|
||||
}
|
||||
|
||||
const DefaultSpeedyDefines = struct {
|
||||
pub const Keys = struct {
|
||||
const window = "window";
|
||||
};
|
||||
pub const Values = struct {
|
||||
const window = "undefined";
|
||||
};
|
||||
};
|
||||
|
||||
pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args: Api.TransformOptions) !Api.TransformOptions {
|
||||
var args = _args;
|
||||
|
||||
@@ -63,6 +72,7 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
|
||||
}
|
||||
}
|
||||
var needs_node_env = env_map.get("NODE_ENV") == null;
|
||||
var needs_window_undefined = true;
|
||||
|
||||
var needs_regenerate = args.define == null and env_count > 0;
|
||||
if (args.define) |def| {
|
||||
@@ -72,12 +82,16 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
|
||||
for (def.keys) |key| {
|
||||
if (strings.eql(key, "process.env.NODE_ENV")) {
|
||||
needs_node_env = false;
|
||||
} else if (strings.eql(key, "window")) {
|
||||
needs_window_undefined = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var extras_count = @intCast(usize, @boolToInt(needs_node_env)) + @intCast(usize, @boolToInt(needs_window_undefined));
|
||||
|
||||
if (needs_regenerate) {
|
||||
var new_list = try allocator.alloc([]const u8, env_count * 2 + @intCast(usize, @boolToInt(needs_node_env)) * 2);
|
||||
var new_list = try allocator.alloc([]const u8, env_count * 2 + extras_count * 2);
|
||||
var keys = new_list[0 .. new_list.len / 2];
|
||||
var values = new_list[keys.len..];
|
||||
var new_map = Api.StringMap{
|
||||
@@ -119,7 +133,16 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
|
||||
if (needs_node_env) {
|
||||
keys[last] = options.DefaultUserDefines.NodeEnv.Key;
|
||||
values[last] = options.DefaultUserDefines.NodeEnv.Value;
|
||||
last += 1;
|
||||
}
|
||||
|
||||
if (needs_window_undefined) {
|
||||
keys[last] = DefaultSpeedyDefines.Keys.window;
|
||||
values[last] = DefaultSpeedyDefines.Values.window;
|
||||
last += 1;
|
||||
}
|
||||
|
||||
args.define = new_map;
|
||||
}
|
||||
|
||||
return args;
|
||||
@@ -130,7 +153,7 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
|
||||
// Its unavailable on Linux
|
||||
pub const VirtualMachine = struct {
|
||||
const RequireCacheType = std.AutoHashMap(u32, *Module);
|
||||
root: js.JSGlobalContextRef,
|
||||
// root: js.JSGlobalContextRef,
|
||||
ctx: js.JSGlobalContextRef = undefined,
|
||||
group: js.JSContextGroupRef,
|
||||
allocator: *std.mem.Allocator,
|
||||
@@ -151,8 +174,6 @@ pub const VirtualMachine = struct {
|
||||
) !*VirtualMachine {
|
||||
var group = js.JSContextGroupRetain(js.JSContextGroupCreate());
|
||||
|
||||
var ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(group, null));
|
||||
|
||||
var log: *logger.Log = undefined;
|
||||
if (_log) |__log| {
|
||||
log = __log;
|
||||
@@ -170,10 +191,10 @@ pub const VirtualMachine = struct {
|
||||
try configureTransformOptionsForSpeedy(allocator, _args),
|
||||
existing_bundle,
|
||||
),
|
||||
.node_module_list = try allocator.create(Module.NodeModuleList),
|
||||
.node_module_list = null,
|
||||
.log = log,
|
||||
.group = group,
|
||||
.root = ctx,
|
||||
|
||||
.require_cache = RequireCacheType.init(allocator),
|
||||
.global = global,
|
||||
};
|
||||
@@ -189,7 +210,9 @@ pub const VirtualMachine = struct {
|
||||
Properties.init();
|
||||
if (vm.bundler.options.node_modules_bundle) |bundle| {
|
||||
vm.node_modules = bundle;
|
||||
vm.node_module_list = try allocator.create(Module.NodeModuleList);
|
||||
try Module.NodeModuleList.create(vm, bundle, vm.node_module_list.?);
|
||||
vm.global.ctx = vm.node_module_list.?.bundle_ctx;
|
||||
}
|
||||
|
||||
return vm;
|
||||
@@ -425,6 +448,7 @@ pub const Module = struct {
|
||||
require_cache: []?*Module,
|
||||
|
||||
exports_function_call: js.JSObjectRef = null,
|
||||
console: js.JSObjectRef = null,
|
||||
|
||||
const RequireBundleClassName = "requireFromBundle";
|
||||
var require_bundle_class_def: js.JSClassDefinition = undefined;
|
||||
@@ -650,6 +674,24 @@ pub const Module = struct {
|
||||
return module.internalGetExports(js.JSContextGetGlobalContext(ctx));
|
||||
}
|
||||
|
||||
pub fn getConsole(
|
||||
ctx: js.JSContextRef,
|
||||
thisObject: js.JSObjectRef,
|
||||
prop: js.JSStringRef,
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
var this = @ptrCast(
|
||||
*NodeModuleList,
|
||||
@alignCast(@alignOf(*NodeModuleList), js.JSObjectGetPrivate(thisObject) orelse return null),
|
||||
);
|
||||
|
||||
if (this.console == null) {
|
||||
this.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), this.vm.global.console_class, this.vm.global);
|
||||
}
|
||||
|
||||
return this.console;
|
||||
}
|
||||
|
||||
pub fn create(vm: *VirtualMachine, bundle: *const NodeModuleBundle, node_module_list: *NodeModuleList) !void {
|
||||
var size: usize = 0;
|
||||
var longest_size: usize = 0;
|
||||
@@ -664,7 +706,13 @@ pub const Module = struct {
|
||||
size += this_size;
|
||||
longest_size = std.math.max(this_size, longest_size);
|
||||
}
|
||||
var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 1);
|
||||
var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 2);
|
||||
static_properties[static_properties.len - 2] = js.JSStaticValue{
|
||||
.name = Properties.UTF8.console[0.. :0],
|
||||
.getProperty = getConsole,
|
||||
.setProperty = null,
|
||||
.attributes = .kJSPropertyAttributeNone,
|
||||
};
|
||||
static_properties[static_properties.len - 1] = std.mem.zeroes(js.JSStaticValue);
|
||||
var utf8 = try vm.allocator.alloc(u8, size + std.math.max(longest_size, 32));
|
||||
std.mem.set(u8, utf8, 0);
|
||||
@@ -780,20 +828,20 @@ pub const Module = struct {
|
||||
|
||||
const len = js.JSStringGetLength(arguments[0]);
|
||||
|
||||
// if (!require_buf_loaded) {
|
||||
// require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
|
||||
// require_buf_loaded = true;
|
||||
// } else {
|
||||
// require_buf.reset();
|
||||
// require_buf.growIfNeeded(len + 1) catch {};
|
||||
// }
|
||||
if (!require_buf_loaded) {
|
||||
require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
|
||||
require_buf_loaded = true;
|
||||
} else {
|
||||
require_buf.reset();
|
||||
require_buf.growIfNeeded(len + 1) catch {};
|
||||
}
|
||||
|
||||
// require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
|
||||
require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
|
||||
|
||||
var require_buf_ = this.vm.allocator.alloc(u8, len + 1) catch unreachable;
|
||||
var end = js.JSStringGetUTF8CString(arguments[0], require_buf_.ptr, require_buf_.len);
|
||||
// var end = js.JSStringGetUTF8CString(arguments[0], require_buf.list.items.ptr, require_buf.list.items.len);
|
||||
var import_path = require_buf_[0 .. end - 1];
|
||||
// var require_buf_ = this.vm.allocator.alloc(u8, len + 1) catch unreachable;
|
||||
// var end = js.JSStringGetUTF8CString(arguments[0], require_buf_.ptr, require_buf_.len);
|
||||
var end = js.JSStringGetUTF8CString(arguments[0], require_buf.list.items.ptr, require_buf.list.items.len);
|
||||
var import_path = require_buf.list.items[0 .. end - 1];
|
||||
var module = this;
|
||||
|
||||
if (this.vm.bundler.linker.resolver.resolve(module.path.name.dirWithTrailingSlash(), import_path, .require)) |resolved| {
|
||||
@@ -803,13 +851,13 @@ pub const Module = struct {
|
||||
|
||||
switch (load_result) {
|
||||
.Module => |new_module| {
|
||||
if (isDebug) {
|
||||
Output.prettyln(
|
||||
"Input: {s}\nOutput: {s}",
|
||||
.{ import_path, load_result.Module.path.text },
|
||||
);
|
||||
Output.flush();
|
||||
}
|
||||
// if (isDebug) {
|
||||
// Output.prettyln(
|
||||
// "Input: {s}\nOutput: {s}",
|
||||
// .{ import_path, load_result.Module.path.text },
|
||||
// );
|
||||
// Output.flush();
|
||||
// }
|
||||
return new_module.internalGetExports(js.JSContextGetGlobalContext(ctx));
|
||||
},
|
||||
.Path => |path| {
|
||||
@@ -862,7 +910,7 @@ pub const Module = struct {
|
||||
|
||||
exports_class_ref = js.JSClassRetain(js.JSClassCreate(&ExportsClass));
|
||||
|
||||
module_class_def = ModuleClass.define(vm.root);
|
||||
module_class_def = ModuleClass.define();
|
||||
module_class = js.JSClassRetain(js.JSClassCreate(&module_class_def));
|
||||
}
|
||||
|
||||
@@ -913,19 +961,18 @@ pub const Module = struct {
|
||||
.vm = vm,
|
||||
};
|
||||
module.ref = js.JSObjectMake(global_ctx, Module.module_class, module);
|
||||
|
||||
js.JSValueProtect(global_ctx, module.ref);
|
||||
|
||||
if (!module_wrapper_loaded) {
|
||||
module_wrapper_params[0] = js.JSStringCreateWithUTF8CString(Properties.UTF8.module[0.. :0]);
|
||||
module_wrapper_params[1] = js.JSStringCreateWithUTF8CString(Properties.UTF8.exports[0.. :0]);
|
||||
module_wrapper_loaded = true;
|
||||
}
|
||||
// if (!module_wrapper_loaded) {
|
||||
module_wrapper_params[0] = js.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.module[0.. :0]));
|
||||
module_wrapper_params[1] = js.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.exports[0.. :0]));
|
||||
// module_wrapper_loaded = true;
|
||||
// }
|
||||
|
||||
var module_wrapper_args: [2]js.JSValueRef = undefined;
|
||||
module_wrapper_args[0] = module.ref;
|
||||
module_wrapper_args[1] = module.internalGetExports(global_ctx);
|
||||
js.JSValueProtect(global_ctx, module_wrapper_args[1]);
|
||||
|
||||
var except: js.JSValueRef = null;
|
||||
go: {
|
||||
var commonjs_wrapper = js.JSObjectMakeFunction(
|
||||
@@ -942,13 +989,14 @@ pub const Module = struct {
|
||||
if (except != null) {
|
||||
break :go;
|
||||
}
|
||||
|
||||
// var module = {exports: {}}; ((module, exports) => {
|
||||
_ = js.JSObjectCallAsFunction(call_ctx, commonjs_wrapper, null, 2, &module_wrapper_args, &except);
|
||||
// module.exports = exports;
|
||||
// })(module, module.exports);
|
||||
|
||||
// module.exports = module_wrapper_args[1];
|
||||
js.JSValueProtect(global_ctx, module.exports);
|
||||
|
||||
js.JSValueUnprotect(global_ctx, commonjs_wrapper);
|
||||
}
|
||||
if (except != null) {
|
||||
@@ -1000,17 +1048,17 @@ pub const Module = struct {
|
||||
.tsx,
|
||||
.json,
|
||||
=> {
|
||||
const package_json_ = resolved.package_json orelse brk: {
|
||||
// package_json is sometimes null when we're loading as an absolute path
|
||||
if (resolved.isLikelyNodeModule()) {
|
||||
break :brk vm.bundler.resolver.packageJSONForResolvedNodeModule(&resolved);
|
||||
}
|
||||
break :brk null;
|
||||
};
|
||||
if (vm.node_modules) |node_modules| {
|
||||
const package_json_ = resolved.package_json orelse brk: {
|
||||
// package_json is sometimes null when we're loading as an absolute path
|
||||
if (resolved.isLikelyNodeModule()) {
|
||||
break :brk vm.bundler.resolver.packageJSONForResolvedNodeModule(&resolved);
|
||||
}
|
||||
break :brk null;
|
||||
};
|
||||
|
||||
if (package_json_) |package_json| {
|
||||
if (package_json.hash > 0) {
|
||||
if (vm.node_modules) |node_modules| {
|
||||
if (package_json_) |package_json| {
|
||||
if (package_json.hash > 0) {
|
||||
if (node_modules.getPackageIDByName(package_json.name)) |possible_package_ids| {
|
||||
const package_id: ?u32 = brk: {
|
||||
for (possible_package_ids) |pid| {
|
||||
@@ -1105,7 +1153,7 @@ pub const Module = struct {
|
||||
vm.log,
|
||||
source_code_printer.ctx.sentinel,
|
||||
path,
|
||||
vm.global.ctx,
|
||||
js.JSContextGetGlobalContext(ctx),
|
||||
ctx,
|
||||
ctx,
|
||||
exception,
|
||||
@@ -1287,7 +1335,6 @@ pub const GlobalObject = struct {
|
||||
console_definition: js.JSClassDefinition = undefined,
|
||||
global_class_def: js.JSClassDefinition = undefined,
|
||||
global_class: js.JSClassRef = undefined,
|
||||
root_obj: js.JSObjectRef = undefined,
|
||||
|
||||
pub const ConsoleClass = NewClass(
|
||||
GlobalObject,
|
||||
@@ -1324,42 +1371,28 @@ pub const GlobalObject = struct {
|
||||
obj: js.JSObjectRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
return global.console;
|
||||
}
|
||||
// if (global.console == null) {
|
||||
// global.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
|
||||
// js.JSValueProtect(js.JSContextGetGlobalContext(ctx), global.console);
|
||||
// }
|
||||
|
||||
pub fn onMissingProperty(
|
||||
global: *GlobalObject,
|
||||
ctx: js.JSContextRef,
|
||||
obj: js.JSObjectRef,
|
||||
prop: js.JSStringRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
if (js.JSObjectHasProperty(ctx, global.root_obj, prop)) {
|
||||
return js.JSObjectGetProperty(ctx, global.root_obj, prop, exception);
|
||||
} else {
|
||||
return js.JSValueMakeUndefined(ctx);
|
||||
}
|
||||
return js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
|
||||
}
|
||||
|
||||
pub fn boot(global: *GlobalObject) !void {
|
||||
var private: ?*c_void = global;
|
||||
global.root_obj = js.JSContextGetGlobalObject(global.vm.root);
|
||||
|
||||
global.console_definition = ConsoleClass.define(global.vm.root);
|
||||
global.console_definition = ConsoleClass.define();
|
||||
global.console_class = js.JSClassRetain(js.JSClassCreate(&global.console_definition));
|
||||
global.console = js.JSObjectMake(global.vm.root, global.console_class, private);
|
||||
|
||||
global.global_class_def = GlobalClass.define(global.vm.root);
|
||||
global.global_class_def = GlobalClass.define();
|
||||
global.global_class = js.JSClassRetain(js.JSClassCreate(&global.global_class_def));
|
||||
|
||||
global.ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(global.vm.group, global.global_class));
|
||||
|
||||
std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), private));
|
||||
global.ref = js.JSContextGetGlobalObject(global.ctx);
|
||||
std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), global));
|
||||
|
||||
if (!printer_buf_loaded) {
|
||||
printer_buf_loaded = true;
|
||||
printer_buf = try MutableString.init(global.vm.allocator, 0);
|
||||
printer_buf = try MutableString.init(global.vm.allocator, 4096);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1562,7 +1595,7 @@ pub fn NewClass(
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
var instance_pointer_ = js.JSObjectGetPrivate(obj);
|
||||
if (instance_pointer_ == null) return js.JSValueMakeUndefined(ctx);
|
||||
if (instance_pointer_ == null) return null;
|
||||
var instance_pointer = instance_pointer_.?;
|
||||
var ptr = @ptrCast(
|
||||
*ZigType,
|
||||
@@ -1610,7 +1643,7 @@ pub fn NewClass(
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
var instance_pointer_ = js.JSObjectGetPrivate(obj);
|
||||
if (instance_pointer_ == null) return js.JSValueMakeUndefined(ctx);
|
||||
if (instance_pointer_ == null) return null;
|
||||
var this: *ZigType = @ptrCast(
|
||||
*ZigType,
|
||||
@alignCast(
|
||||
@@ -1634,7 +1667,7 @@ pub fn NewClass(
|
||||
)(
|
||||
this,
|
||||
ctx,
|
||||
this.ref,
|
||||
obj,
|
||||
exception,
|
||||
);
|
||||
},
|
||||
@@ -1648,7 +1681,7 @@ pub fn NewClass(
|
||||
)(
|
||||
this,
|
||||
ctx,
|
||||
this.ref,
|
||||
obj,
|
||||
prop,
|
||||
exception,
|
||||
);
|
||||
@@ -1692,7 +1725,7 @@ pub fn NewClass(
|
||||
)(
|
||||
this,
|
||||
ctx,
|
||||
this.ref,
|
||||
obj,
|
||||
prop,
|
||||
value,
|
||||
exception,
|
||||
@@ -1704,16 +1737,14 @@ pub fn NewClass(
|
||||
};
|
||||
}
|
||||
|
||||
pub fn define(ctx: js.JSContextRef) js.JSClassDefinition {
|
||||
pub fn define() js.JSClassDefinition {
|
||||
var def = js.kJSClassDefinitionEmpty;
|
||||
|
||||
if (static_functions.len > 0) {
|
||||
std.mem.set(js.JSStaticFunction, &static_functions, std.mem.zeroes(js.JSStaticFunction));
|
||||
|
||||
inline for (function_name_literals) |function_name, i| {
|
||||
var callback = To.JS.Callback(ZigType, @field(staticFunctions, function_names[i])).rfn;
|
||||
function_name_refs[i] = js.JSStringCreateWithCharactersNoCopy(
|
||||
function_name.ptr,
|
||||
function_name.len,
|
||||
);
|
||||
|
||||
static_functions[i] = js.JSStaticFunction{
|
||||
.name = (function_names[i][0.. :0]).ptr,
|
||||
@@ -1725,6 +1756,7 @@ pub fn NewClass(
|
||||
// instance_functions[i] = function;
|
||||
// }
|
||||
}
|
||||
|
||||
def.staticFunctions = &static_functions;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user