aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/javascript/jsc/javascript.zig198
1 files changed, 169 insertions, 29 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index 7cc64a2f6..e1065f53b 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -19,6 +19,7 @@ const NetworkThread = @import("http").NetworkThread;
pub fn zigCast(comptime Destination: type, value: anytype) *Destination {
return @ptrCast(*Destination, @alignCast(@alignOf(*Destination), value));
}
+const Allocator = std.mem.Allocator;
const IdentityContext = @import("../../identity_context.zig").IdentityContext;
const Fs = @import("../../fs.zig");
const Resolver = @import("../../resolver/resolver.zig");
@@ -1705,6 +1706,7 @@ pub const Task = TaggedPointerUnion(.{
});
const SourceMap = @import("../../sourcemap/sourcemap.zig");
+const MappingList = SourceMap.Mapping.List;
pub const SavedSourceMap = struct {
// For bun.js, we store the number of mappings and how many bytes the final list is at the beginning of the array
@@ -1718,26 +1720,65 @@ pub const SavedSourceMap = struct {
}
pub inline fn len(this: SavedMappings) usize {
- return @bitCast(u64, this.data[0..8]);
+ return @bitCast(u64, this.data[0..8].*);
}
- pub fn deinit(this: SavedMappings) []u8 {
+ pub fn deinit(this: SavedMappings) void {
default_allocator.free(this.data[0..this.len()]);
}
+
+ pub fn toMapping(this: SavedMappings, allocator: Allocator, path: string) anyerror!MappingList {
+ const result = SourceMap.Mapping.parse(
+ allocator,
+ this.data[16..this.len()],
+ @bitCast(usize, this.data[8..16].*),
+ 1,
+ );
+ switch (result) {
+ .fail => |fail| {
+ if (Output.enable_ansi_colors_stderr) {
+ try fail.toData(path).writeFormat(
+ Output.errorWriter(),
+ logger.Kind.warn,
+ true,
+ false,
+ );
+ } else {
+ try fail.toData(path).writeFormat(
+ Output.errorWriter(),
+ logger.Kind.warn,
+ false,
+ false,
+ );
+ }
+
+ return fail.err;
+ },
+ .success => |success| {
+ return success;
+ },
+ }
+ }
};
- pub const Value = TaggedPointerUnion(.{ SourceMap, SavedMappings });
+ pub const Value = TaggedPointerUnion(.{ MappingList, SavedMappings });
pub const HashTable = std.HashMap(u64, *anyopaque, IdentityContext(u64), 80);
map: HashTable,
+ pub fn onSourceMapChunk(this: *SavedSourceMap, chunk: SourceMap.Chunk, source: logger.Source) anyerror!void {
+ try this.putMappings(source, chunk.buffer);
+ }
+
+ pub const SourceMapHandler = js_printer.SourceMapHandler.For(SavedSourceMap, onSourceMapChunk);
+
pub fn putMappings(this: *SavedSourceMap, source: logger.Source, mappings: MutableString) !void {
var entry = try this.map.getOrPut(std.hash.Wyhash.hash(0, source.path.text));
if (entry.found_existing) {
var value = Value.from(entry.value_ptr.*);
- if (value.get(SourceMap)) |source_map_| {
- var source_map: *SourceMap = source_map_;
- source_map.deinit();
+ if (value.get(MappingList)) |source_map_| {
+ var source_map: *MappingList = source_map_;
+ source_map.deinit(default_allocator);
} else if (value.get(SavedMappings)) |saved_mappings| {
var saved = SavedMappings{ .data = @ptrCast([*]u8, saved_mappings) };
@@ -1745,22 +1786,39 @@ pub const SavedSourceMap = struct {
}
}
- entry.value_ptr.* = Value.init(@ptrCast(*SavedMappings, mappings.list.items.ptr)).ptr();
+ entry.value_ptr.* = Value.init(bun.cast(*SavedMappings, mappings.list.items.ptr)).ptr();
}
- pub fn get(this: *SavedSourceMap, allocator: std.mem.Allocator, path: string) ?*SourceMap {
+ pub fn get(this: *SavedSourceMap, path: string) ?MappingList {
var mapping = this.map.getEntry(std.hash.Wyhash.hash(0, path)) orelse return null;
switch (Value.from(mapping.value_ptr.*).tag()) {
- SourceMap => {
- return Value.from(mapping).as(SourceMap);
+ (@field(Value.Tag, @typeName(MappingList))) => {
+ return Value.from(mapping.value_ptr.*).as(MappingList).*;
},
- SavedMappings => {
- _ = allocator;
- return null;
+ Value.Tag.SavedMappings => {
+ var saved = SavedMappings{ .data = @ptrCast([*]u8, Value.from(mapping.value_ptr.*).as(MappingList)) };
+ defer saved.deinit();
+ var result = default_allocator.create(MappingList) catch unreachable;
+ result.* = saved.toMapping(default_allocator, path) catch {
+ _ = this.map.remove(mapping.key_ptr.*);
+ return null;
+ };
+ mapping.value_ptr.* = Value.init(result).ptr();
+ return result.*;
},
else => return null,
}
}
+
+ pub fn resolveMapping(
+ this: *SavedSourceMap,
+ path: []const u8,
+ line: i32,
+ column: i32,
+ ) ?SourceMap.Mapping {
+ var mappings = this.get(path) orelse return null;
+ return SourceMap.Mapping.find(mappings, line, column);
+ }
};
// If you read JavascriptCore/API/JSVirtualMachine.mm - https://github.com/WebKit/WebKit/blob/acff93fb303baa670c055cb24c2bad08691a01a0/Source/JavaScriptCore/API/JSVirtualMachine.mm#L101
@@ -2085,6 +2143,7 @@ pub const VirtualMachine = struct {
_specifier: string,
_: string,
log: *logger.Log,
+ comptime disable_transpilying: bool,
) !ResolvedSource {
std.debug.assert(VirtualMachine.vm_loaded);
var jsc_vm = vm;
@@ -2117,6 +2176,15 @@ pub const VirtualMachine = struct {
// so it consistently handles bundled imports
// we can't take the shortcut of just directly importing the file, sadly.
} else if (strings.eqlComptime(_specifier, main_file_name)) {
+ if (comptime disable_transpilying) {
+ return ResolvedSource{
+ .allocator = null,
+ .source_code = ZigString.init(jsc_vm.entry_point.source.contents),
+ .specifier = ZigString.init(std.mem.span(main_file_name)),
+ .source_url = ZigString.init(std.mem.span(main_file_name)),
+ .hash = 0,
+ };
+ }
defer jsc_vm.transpiled_count += 1;
var bundler = &jsc_vm.bundler;
@@ -2160,11 +2228,12 @@ pub const VirtualMachine = struct {
printer.ctx.reset();
{
defer source_code_printer.?.* = printer;
- written = try jsc_vm.bundler.print(
+ written = try jsc_vm.bundler.printWithSourceMap(
parse_result,
@TypeOf(&printer),
&printer,
.esm_ascii,
+ SavedSourceMap.SourceMapHandler.init(&jsc_vm.source_mappings),
);
}
@@ -2182,14 +2251,16 @@ pub const VirtualMachine = struct {
} else if (_specifier.len > js_ast.Macro.namespaceWithColon.len and
strings.eqlComptimeIgnoreLen(_specifier[0..js_ast.Macro.namespaceWithColon.len], js_ast.Macro.namespaceWithColon))
{
- if (jsc_vm.macro_entry_points.get(MacroEntryPoint.generateIDFromSpecifier(_specifier))) |entry| {
- return ResolvedSource{
- .allocator = null,
- .source_code = ZigString.init(entry.source.contents),
- .specifier = ZigString.init(_specifier),
- .source_url = ZigString.init(_specifier),
- .hash = 0,
- };
+ if (comptime !disable_transpilying) {
+ if (jsc_vm.macro_entry_points.get(MacroEntryPoint.generateIDFromSpecifier(_specifier))) |entry| {
+ return ResolvedSource{
+ .allocator = null,
+ .source_code = ZigString.init(entry.source.contents),
+ .specifier = ZigString.init(_specifier),
+ .source_url = ZigString.init(_specifier),
+ .hash = 0,
+ };
+ }
}
} else if (strings.eqlComptime(_specifier, "node:fs")) {
return ResolvedSource{
@@ -2275,13 +2346,24 @@ pub const VirtualMachine = struct {
}
}
- var parse_result = jsc_vm.bundler.parse(
+ var parse_result = jsc_vm.bundler.parseMaybeReturnFileOnly(
parse_options,
null,
+ disable_transpilying,
) orelse {
return error.ParseError;
};
+ if (comptime disable_transpilying) {
+ return ResolvedSource{
+ .allocator = null,
+ .source_code = ZigString.init(parse_result.source.contents),
+ .specifier = ZigString.init(specifier),
+ .source_url = ZigString.init(path.text),
+ .hash = 0,
+ };
+ }
+
const start_count = jsc_vm.bundler.linker.import_counter;
// We _must_ link because:
// - node_modules bundle won't be properly
@@ -2302,11 +2384,12 @@ pub const VirtualMachine = struct {
printer.ctx.reset();
{
defer source_code_printer.?.* = printer;
- written = try jsc_vm.bundler.print(
+ written = try jsc_vm.bundler.printWithSourceMap(
parse_result,
@TypeOf(&printer),
&printer,
.esm_ascii,
+ SavedSourceMap.SourceMapHandler.init(&jsc_vm.source_mappings),
);
}
@@ -2565,7 +2648,7 @@ pub const VirtualMachine = struct {
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) void {
var log = logger.Log.init(vm.bundler.allocator);
const spec = specifier.slice();
- const result = _fetch(global, spec, source.slice(), &log) catch |err| {
+ const result = _fetch(global, spec, source.slice(), &log, false) catch |err| {
processFetchLog(global, specifier, source, &log, ret, err);
return;
};
@@ -2987,14 +3070,71 @@ pub const VirtualMachine = struct {
}
}
- pub fn printErrorInstance(this: *VirtualMachine, error_instance: JSValue, exception_list: ?*ExceptionList, comptime Writer: type, writer: Writer, comptime allow_ansi_color: bool) !void {
- var exception_holder = ZigException.Holder.init();
- var exception = exception_holder.zigException();
- error_instance.toZigException(vm.global, exception);
+ fn remapZigException(
+ this: *VirtualMachine,
+ exception: *ZigException,
+ error_instance: JSValue,
+ exception_list: ?*ExceptionList,
+ ) !void {
+ error_instance.toZigException(this.global, exception);
if (exception_list) |list| {
try exception.addToErrorList(list);
}
+ var frames: []JSC.ZigStackFrame = exception.stack.frames_ptr[0..exception.stack.frames_len];
+ if (frames.len == 0) return;
+
+ var top = &frames[0];
+ if (this.source_mappings.resolveMapping(
+ top.source_url.slice(),
+ @maximum(top.position.line, 0),
+ @maximum(top.position.column_stop, 0),
+ )) |mapping| {
+ var log = logger.Log.init(default_allocator);
+ var original_source = _fetch(this.global, top.source_url.slice(), "", &log, true) catch return;
+ const code = original_source.source_code.slice();
+ top.position.line = mapping.original.lines;
+ top.position.column_start = mapping.original.columns;
+ top.position.expression_start = mapping.original.columns;
+ if (strings.getLinesInText(
+ code,
+ @intCast(u32, top.position.line),
+ JSC.ZigException.Holder.source_lines_count,
+ )) |lines| {
+ var source_lines = exception.stack.source_lines_ptr[0..JSC.ZigException.Holder.source_lines_count];
+ var source_line_numbers = exception.stack.source_lines_numbers[0..JSC.ZigException.Holder.source_lines_count];
+ std.mem.set(ZigString, source_lines, ZigString.Empty);
+ std.mem.set(i32, source_line_numbers, 0);
+
+ var lines_ = lines[0..@minimum(lines.len, source_lines.len)];
+ for (lines_) |line, j| {
+ source_lines[(lines_.len - 1) - j] = ZigString.init(line);
+ source_line_numbers[j] = top.position.line - @intCast(i32, j) + 1;
+ }
+
+ exception.stack.source_lines_len = @intCast(u8, lines_.len);
+ }
+ }
+
+ if (frames.len > 1) {
+ for (frames[1..]) |*frame| {
+ if (frame.position.isInvalid()) continue;
+ if (this.source_mappings.resolveMapping(
+ frame.source_url.slice(),
+ @maximum(frame.position.line, 0),
+ @maximum(frame.position.column_start, 0),
+ )) |mapping| {
+ frame.position.line = mapping.original.lines;
+ frame.position.column_start = mapping.original.columns;
+ }
+ }
+ }
+ }
+
+ pub fn printErrorInstance(this: *VirtualMachine, error_instance: JSValue, exception_list: ?*ExceptionList, comptime Writer: type, writer: Writer, comptime allow_ansi_color: bool) !void {
+ var exception_holder = ZigException.Holder.init();
+ var exception = exception_holder.zigException();
+ try this.remapZigException(exception, error_instance, exception_list);
this.had_errors = true;
var line_numbers = exception.stack.source_lines_numbers[0..exception.stack.source_lines_len];