Compare commits

...

13 Commits

Author SHA1 Message Date
Claude Bot
5745fd986e Remove isEmpty() check - inject synthetic frames even if stack exists
Still not working - stack trace unchanged. Need to investigate further
why synthetic sourceURL/line/column aren't being used.
2025-10-06 03:35:17 +00:00
Claude Bot
b3e705a428 Add synthetic stack frame injection for BuildMessage/ResolveMessage
- Inject synthetic frames in computeErrorInfo when stack is empty
- Use BuildMessage/ResolveMessage location data for file/line/column
- Works for both toString and toJSValue error formatting paths

Note: Stack still shows bundler frames - likely captured earlier during throw.
Source preview still wrong - pre-existing issue with line_text pointing to wrong buffer.
2025-10-06 03:35:17 +00:00
Claude Bot
873acbc28e Add synthetic stack frame creation for BuildMessage/ResolveMessage
- Add BuildMessage__createSyntheticStackFrame export
- Add ResolveMessage__createSyntheticStackFrame export
- These create ZigStackFrame with correct file/line/column from location data
- Still need to wire up injection into ErrorInstance stack

WIP: Stack trace still showing bundler frames, needs synthetic frame injection
2025-10-06 03:35:17 +00:00
autofix-ci[bot]
c888f9c3bb [autofix.ci] apply automated fixes 2025-10-06 01:37:06 +00:00
Claude Bot
0c8866f60f WIP: Fix BuildMessage/ResolveMessage error formatting
- Remove duplicate Bun__errorInstance__finalize in ErrorStackTrace.cpp
- Restore msg.clone() in BuildMessage.create() to preserve line_text
- Set clone_line_text=true in VirtualMachine resolve log
- Disable automatic stack capture for BuildMessage/ResolveMessage ErrorInstances
- Clear stack trace in computeErrorInfo for BuildMessage/ResolveMessage
- Return false from printErrorFromMaybePrivateData to suppress stack printing

Note: Stack trace still appears in output - needs further investigation
2025-10-06 01:35:27 +00:00
Claude Bot
a6f93de862 Merge main into jarred/fix-resolvebuild-error 2025-10-06 00:45:52 +00:00
autofix-ci[bot]
b9f54ce3c6 [autofix.ci] apply automated fixes 2025-09-29 23:49:56 +00:00
Jarred Sumner
403e762005 a 2025-09-29 16:48:07 -07:00
Jarred Sumner
e23b06657e Update BuildMessage.zig 2025-09-29 16:15:43 -07:00
Jarred Sumner
c75ecfedd6 Update BuildMessage.zig 2025-09-29 16:15:19 -07:00
Jarred Sumner
2a3067c1af Update BuildMessage.zig 2025-09-29 16:15:19 -07:00
autofix-ci[bot]
a10d1561a4 [autofix.ci] apply automated fixes 2025-09-29 23:13:06 +00:00
Jarred Sumner
78abbcb80c De-slop most of this 2025-09-29 16:11:20 -07:00
21 changed files with 1021 additions and 165 deletions

View File

@@ -1,8 +1,6 @@
pub const BuildMessage = struct {
pub const js = jsc.Codegen.JSBuildMessage;
pub const toJS = js.toJS;
pub const fromJS = js.fromJS;
pub const fromJSDirect = js.fromJSDirect;
// Remove codegen references since we're not using the class generator anymore
pub extern fn BuildMessage__toJS(*BuildMessage, *jsc.JSGlobalObject) jsc.JSValue;
msg: logger.Msg,
// resolve_result: Resolver.Result,
@@ -49,14 +47,21 @@ pub const BuildMessage = struct {
msg: logger.Msg,
// resolve_result: *const Resolver.Result,
) bun.OOM!jsc.JSValue {
var build_error = try allocator.create(BuildMessage);
const build_error = try allocator.create(BuildMessage);
// Clone the msg to preserve line_text and other location data
// The source buffer may be reused/deallocated after the error is created
build_error.* = BuildMessage{
.msg = try msg.clone(allocator),
// .resolve_result = resolve_result.*,
.allocator = allocator,
};
return build_error.toJS(globalThis);
// Pass the actual BuildMessage pointer, the C++ side will create and store the tagged pointer
return BuildMessage__toJS(build_error, globalThis);
}
pub fn toJS(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return BuildMessage__toJS(this, globalThis);
}
pub fn toString(
@@ -96,7 +101,7 @@ pub const BuildMessage = struct {
var object = jsc.JSValue.createEmptyObject(globalThis, 4);
object.put(globalThis, ZigString.static("name"), bun.String.static("BuildMessage").toJS(globalThis));
object.put(globalThis, ZigString.static("position"), this.getPosition(globalThis));
object.put(globalThis, ZigString.static("message"), this.getMessage(globalThis));
object.put(globalThis, ZigString.static("message"), try bun.String.createUTF8ForJS(globalThis, this.msg.data.text));
object.put(globalThis, ZigString.static("level"), this.getLevel(globalThis));
return object;
}
@@ -168,11 +173,8 @@ pub const BuildMessage = struct {
return BuildMessage.generatePositionObject(this.msg, globalThis);
}
pub fn getMessage(
this: *BuildMessage,
globalThis: *jsc.JSGlobalObject,
) jsc.JSValue {
return ZigString.init(this.msg.data.text).toJS(globalThis);
pub fn getMessageString(this: *BuildMessage) bun.String {
return bun.String.init(this.msg.data.text);
}
pub fn getLevel(
@@ -185,10 +187,84 @@ pub const BuildMessage = struct {
pub fn finalize(this: *BuildMessage) void {
this.msg.deinit(bun.default_allocator);
}
pub fn fromJS(value: jsc.JSValue) ?*BuildMessage {
const bun_error_data = BunErrorData.fromJS(value) orelse return null;
if (bun_error_data.is(BuildMessage)) {
return bun_error_data.as(BuildMessage);
}
return null;
}
pub export fn BuildMessage__fromJS(value: jsc.JSValue) ?*BuildMessage {
return BuildMessage.fromJS(value);
}
pub export fn BuildMessage__getMessageString(this: *BuildMessage) bun.String {
return this.getMessageString();
}
pub export fn BuildMessage__getLevel(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getLevel(globalThis);
}
pub export fn BuildMessage__getPosition(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getPosition(globalThis);
}
pub export fn BuildMessage__getNotes(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getNotes(globalThis) catch globalThis.throwOutOfMemoryValue();
}
pub export fn BuildMessage__getLine(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getLine(globalThis);
}
pub export fn BuildMessage__getColumn(this: *BuildMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getColumn(globalThis);
}
pub export fn BuildMessage__toString(this: *BuildMessage, globalThis: *jsc.JSGlobalObject, _: *jsc.CallFrame) jsc.JSValue {
return this.toStringFn(globalThis);
}
pub export fn BuildMessage__toJSON(this: *BuildMessage, globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) jsc.JSValue {
return this.toJSON(globalThis, callframe) catch globalThis.throwOutOfMemoryValue();
}
pub export fn BuildMessage__toPrimitive(this: *BuildMessage, globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) jsc.JSValue {
return this.toPrimitive(globalThis, callframe) catch jsc.JSValue.jsNull();
}
/// Create a synthetic stack frame for error stack traces
pub export fn BuildMessage__createSyntheticStackFrame(this: *BuildMessage, frame: *jsc.ZigStackFrame) void {
const location = this.msg.data.location orelse {
frame.* = jsc.ZigStackFrame.Zero;
return;
};
frame.* = .{
.function_name = bun.String.empty,
.source_url = bun.String.init(location.file),
.position = .{
.line = bun.Ordinal.fromOneBased(location.line),
.column = bun.Ordinal.fromOneBased(location.column),
.line_start_byte = -1,
},
.code_type = .None,
.is_async = false,
.remapped = true, // Mark as remapped so it's not processed again
};
}
pub export fn BuildMessage__finalize(this: *BuildMessage) void {
this.finalize();
}
};
const string = []const u8;
const BunErrorData = @import("./BunErrorData.zig");
const std = @import("std");
const Resolver = @import("../resolver//resolver.zig").Resolver;

View File

@@ -0,0 +1,52 @@
/// TaggedPointerUnion for different error data types that can be attached to ErrorInstance
pub const BunErrorData = TaggedPointerUnion(.{
BuildMessage,
ResolveMessage,
});
extern fn JSC__JSErrorInstance__bunErrorData(JSValue0: jsc.JSValue) ?*anyopaque;
/// Get BuildMessage from tagged pointer (returns null if not a BuildMessage)
pub export fn Bun__getBuildMessage(ptr: ?*anyopaque) ?*BuildMessage {
if (ptr == null) return null;
const data = BunErrorData.from(ptr);
if (!data.is(BuildMessage)) return null;
return data.as(BuildMessage);
}
/// Get ResolveMessage from tagged pointer (returns null if not a ResolveMessage)
pub export fn Bun__getResolveMessage(ptr: ?*anyopaque) ?*ResolveMessage {
if (ptr == null) return null;
const data = BunErrorData.from(ptr);
if (!data.is(ResolveMessage)) return null;
return data.as(ResolveMessage);
}
/// Finalize the bunErrorData based on its type
pub export fn Bun__errorInstance__finalize(ptr: ?*anyopaque) void {
if (ptr == null) return;
const data = BunErrorData.from(ptr);
if (data.is(BuildMessage)) {
const build_message = data.as(BuildMessage);
build_message.finalize();
bun.destroy(build_message);
} else if (data.is(ResolveMessage)) {
const resolve_message = data.as(ResolveMessage);
resolve_message.finalize();
bun.destroy(resolve_message);
}
}
pub fn fromJS(value: jsc.JSValue) ?BunErrorData {
const ptr = JSC__JSErrorInstance__bunErrorData(value);
if (ptr == null) return null;
return BunErrorData.from(ptr);
}
const BuildMessage = @import("./BuildMessage.zig").BuildMessage;
const ResolveMessage = @import("./ResolveMessage.zig").ResolveMessage;
const bun = @import("bun");
const TaggedPointerUnion = bun.TaggedPointerUnion;
const jsc = bun.jsc;

View File

@@ -1,8 +1,6 @@
pub const ResolveMessage = struct {
pub const js = jsc.Codegen.JSResolveMessage;
pub const toJS = js.toJS;
pub const fromJS = js.fromJS;
pub const fromJSDirect = js.fromJSDirect;
// Remove codegen references since we're not using the class generator anymore
pub extern fn ResolveMessage__toJS(*ResolveMessage, *jsc.JSGlobalObject) jsc.JSValue;
msg: logger.Msg,
allocator: std.mem.Allocator,
@@ -169,13 +167,21 @@ pub const ResolveMessage = struct {
msg: logger.Msg,
referrer: string,
) bun.OOM!jsc.JSValue {
var resolve_error = try allocator.create(ResolveMessage);
const resolve_error = try allocator.create(ResolveMessage);
// Don't clone the msg - the metadata.resolve ranges point to offsets in msg.data.text
// Cloning creates a new text buffer but keeps the same ranges, causing use-after-poison
resolve_error.* = ResolveMessage{
.msg = try msg.clone(allocator),
.msg = msg,
.allocator = allocator,
.referrer = Fs.Path.init(referrer),
};
return resolve_error.toJS(globalThis);
// Pass the actual ResolveMessage pointer, the C++ side will create and store the tagged pointer
return ResolveMessage__toJS(resolve_error, globalThis);
}
pub fn toJS(this: *ResolveMessage, globalThis: *JSGlobalObject) jsc.JSValue {
return ResolveMessage__toJS(this, globalThis);
}
pub fn getPosition(
@@ -192,6 +198,12 @@ pub const ResolveMessage = struct {
return ZigString.init(this.msg.data.text).toJS(globalThis);
}
pub fn getMessageString(
this: *const ResolveMessage,
) bun.String {
return bun.String.init(this.msg.data.text);
}
pub fn getLevel(
this: *ResolveMessage,
globalThis: *jsc.JSGlobalObject,
@@ -227,10 +239,101 @@ pub const ResolveMessage = struct {
pub fn finalize(this: *ResolveMessage) callconv(.C) void {
this.msg.deinit(bun.default_allocator);
}
pub fn fromJS(value: jsc.JSValue) ?*ResolveMessage {
const bun_error_data = BunErrorData.fromJS(value) orelse return null;
if (bun_error_data.is(ResolveMessage)) {
return bun_error_data.as(ResolveMessage);
}
return null;
}
pub export fn ResolveMessage__fromJS(value: jsc.JSValue) ?*ResolveMessage {
return ResolveMessage.fromJS(value);
}
// Export functions for C++ bindings
pub export fn ResolveMessage__getMessage(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getMessage(globalThis);
}
pub export fn ResolveMessage__getMessageString(this: *ResolveMessage) bun.String {
return this.getMessageString();
}
pub export fn ResolveMessage__getCode(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getCode(globalThis);
}
pub export fn ResolveMessage__getLevel(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getLevel(globalThis);
}
pub export fn ResolveMessage__getReferrer(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getReferrer(globalThis);
}
pub export fn ResolveMessage__getSpecifier(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getSpecifier(globalThis);
}
pub export fn ResolveMessage__getImportKind(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getImportKind(globalThis);
}
pub export fn ResolveMessage__getPosition(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getPosition(globalThis);
}
pub export fn ResolveMessage__getLine(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getLine(globalThis);
}
pub export fn ResolveMessage__getColumn(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject) jsc.JSValue {
return this.getColumn(globalThis);
}
pub export fn ResolveMessage__toString(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject, _: *jsc.CallFrame) jsc.JSValue {
return this.toStringFn(globalThis);
}
pub export fn ResolveMessage__toJSON(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) jsc.JSValue {
return this.toJSON(globalThis, callframe) catch globalThis.throwOutOfMemoryValue();
}
pub export fn ResolveMessage__toPrimitive(this: *ResolveMessage, globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) jsc.JSValue {
return this.toPrimitive(globalThis, callframe) catch jsc.JSValue.jsNull();
}
/// Create a synthetic stack frame for error stack traces
pub export fn ResolveMessage__createSyntheticStackFrame(this: *ResolveMessage, frame: *jsc.ZigStackFrame) void {
const location = this.msg.data.location orelse {
frame.* = jsc.ZigStackFrame.Zero;
return;
};
frame.* = .{
.function_name = bun.String.empty,
.source_url = bun.String.init(location.file),
.position = .{
.line = bun.Ordinal.fromOneBased(location.line),
.column = bun.Ordinal.fromOneBased(location.column),
.line_start_byte = -1,
},
.code_type = .None,
.is_async = false,
.remapped = true, // Mark as remapped so it's not processed again
};
}
pub export fn ResolveMessage__finalize(this: *ResolveMessage) void {
this.finalize();
}
};
const string = []const u8;
const BunErrorData = @import("./BunErrorData.zig");
const Resolver = @import("../resolver//resolver.zig");
const std = @import("std");

View File

@@ -1777,6 +1777,7 @@ pub fn resolveMaybeNeedsTrailingSlash(
const old_log = jsc_vm.log;
// the logger can end up being called on another thread, it must not use threadlocal Heap Allocator
var log = logger.Log.init(bun.default_allocator);
log.clone_line_text = true; // Clone line_text to prevent use-after-free when source buffers are recycled
defer log.deinit();
jsc_vm.log = &log;
jsc_vm.transpiler.resolver.log = &log;
@@ -2452,7 +2453,9 @@ fn printErrorFromMaybePrivateData(
build_error.msg,
) catch {};
}
return true;
// Return false to suppress the JavaScript stack trace
// BuildMessage already shows the source location via writeFormat()
return false;
} else if (value.as(bun.api.ResolveMessage)) |resolve_error| {
defer Output.flush();
if (!resolve_error.logged) {
@@ -2471,7 +2474,9 @@ fn printErrorFromMaybePrivateData(
resolve_error.msg,
) catch {};
}
return true;
// Return false to suppress the JavaScript stack trace
// ResolveMessage already shows the source location via writeFormat()
return false;
}
}

View File

@@ -9,6 +9,7 @@
#include "JSEventTarget.h"
#include "JSWorker.h"
#include <JavaScriptCore/ObjectConstructor.h>
#include <JavaScriptCore/ErrorInstance.h>
#include "JSFetchHeaders.h"
#include "JSURLSearchParams.h"
@@ -26,8 +27,8 @@ JSValue BunInjectedScriptHost::subtype(JSGlobalObject* exec, JSValue value)
{
VM& vm = exec->vm();
if (
value.inherits<JSDOMException>() || value.inherits<JSResolveMessage>() || value.inherits<JSBuildMessage>())
// Check for DOMException
if (value.inherits<JSDOMException>())
return jsNontrivialString(vm, "error"_s);
return jsUndefined();

View File

@@ -0,0 +1,15 @@
#include "root.h"
#include <JavaScriptCore/ErrorInstance.h>
extern "C" void* JSC__JSErrorInstance__bunErrorData(JSC::EncodedJSValue value)
{
JSC::JSValue jsValue = JSC::JSValue::decode(value);
if (!jsValue || !jsValue.isCell())
return nullptr;
auto* errorInstance = JSC::jsDynamicCast<JSC::ErrorInstance*>(jsValue);
if (!errorInstance)
return nullptr;
return errorInstance->bunErrorData();
}

View File

@@ -800,8 +800,3 @@ String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const
return functionName;
}
}
extern "C" void Bun__errorInstance__finalize(void* bunErrorData)
{
UNUSED_PARAM(bunErrorData);
}

View File

@@ -0,0 +1,220 @@
#include "root.h"
#include <JavaScriptCore/ObjectConstructor.h>
#include <JavaScriptCore/ErrorInstance.h>
#include <JavaScriptCore/ErrorInstanceInlines.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/FunctionPrototype.h>
#include "JSBuildMessage.h"
#include "JSBuildMessageConstructor.h"
#include "ZigGlobalObject.h"
#include "BunClientData.h"
#include "WebCoreJSBuiltins.h"
#include <JavaScriptCore/PropertySlot.h>
namespace Bun {
// Forward declaration - BuildMessage is defined in Zig
typedef void BuildMessage;
extern "C" void* BuildMessage__fromJS(JSC::EncodedJSValue value);
// External Zig functions
extern "C" BunString BuildMessage__getMessageString(void* buildMessage);
extern "C" JSC::EncodedJSValue BuildMessage__getLevel(void* buildMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue BuildMessage__getPosition(void* buildMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue BuildMessage__getNotes(void* buildMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue BuildMessage__getLine(void* buildMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue BuildMessage__getColumn(void* buildMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue BuildMessage__toString(void* buildMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" JSC::EncodedJSValue BuildMessage__toJSON(void* buildMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" JSC::EncodedJSValue BuildMessage__toPrimitive(void* buildMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" void BuildMessage__finalize(void* buildMessage);
// External functions to unwrap tagged pointer
extern "C" void* Bun__getBuildMessage(void* taggedPtr);
// Custom getter definitions
JSC_DEFINE_CUSTOM_GETTER(jsBuildMessageGetter_level, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* buildMessage = BuildMessage__fromJS(thisValue);
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__getLevel(buildMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsBuildMessageGetter_position, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* buildMessage = BuildMessage__fromJS(thisValue);
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__getPosition(buildMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsBuildMessageGetter_notes, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* buildMessage = BuildMessage__fromJS(thisValue);
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__getNotes(buildMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsBuildMessageGetter_line, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* buildMessage = BuildMessage__fromJS(thisValue);
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__getLine(buildMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsBuildMessageGetter_column, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* buildMessage = BuildMessage__fromJS(thisValue);
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__getColumn(buildMessage, globalObject);
}
// Function implementations
JSC_DEFINE_HOST_FUNCTION(jsBuildMessageFunction_toString, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* buildMessage = BuildMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__toString(buildMessage, globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(jsBuildMessageFunction_toJSON, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* buildMessage = BuildMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__toJSON(buildMessage, globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(jsBuildMessageFunction_toPrimitive, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* buildMessage = BuildMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!buildMessage)
return JSC::JSValue::encode(jsUndefined());
return BuildMessage__toPrimitive(buildMessage, globalObject, callFrame);
}
// HashTable for prototype properties
static const HashTableValue BuildMessagePrototypeValues[] = {
{ "level"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBuildMessageGetter_level, 0 } },
{ "position"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBuildMessageGetter_position, 0 } },
{ "notes"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBuildMessageGetter_notes, 0 } },
{ "line"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBuildMessageGetter_line, 0 } },
{ "column"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBuildMessageGetter_column, 0 } },
{ "toString"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBuildMessageFunction_toString, 0 } },
{ "toJSON"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBuildMessageFunction_toJSON, 0 } },
};
// Prototype class definition
class BuildMessagePrototype : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static constexpr unsigned StructureFlags = Base::StructureFlags;
DECLARE_INFO;
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
// Set prototype to ErrorPrototype
return Structure::create(vm, globalObject, globalObject->errorPrototype(), TypeInfo(ObjectType, StructureFlags), info());
}
static BuildMessagePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
{
BuildMessagePrototype* prototype = new (NotNull, JSC::allocateCell<BuildMessagePrototype>(vm)) BuildMessagePrototype(vm, structure);
prototype->finishCreation(vm, globalObject);
return prototype;
}
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(BuildMessagePrototype, Base);
return &vm.plainObjectSpace();
}
void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, BuildMessagePrototype::info(), BuildMessagePrototypeValues, *this);
// Add name property
this->putDirect(vm, vm.propertyNames->name, JSC::jsString(vm, String("BuildMessage"_s)), PropertyAttribute::DontEnum | 0);
// Add @@toPrimitive
this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol,
JSC::JSFunction::create(vm, globalObject, 1, String(), jsBuildMessageFunction_toPrimitive, ImplementationVisibility::Private),
PropertyAttribute::DontEnum | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
BuildMessagePrototype(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure)
{
}
};
const ClassInfo BuildMessagePrototype::s_info = {
"BuildMessage"_s,
&Base::s_info,
nullptr,
nullptr,
CREATE_METHOD_TABLE(BuildMessagePrototype)
};
void setupJSBuildMessageClassStructure(JSC::LazyClassStructure::Initializer& init)
{
auto* prototypeStructure = BuildMessagePrototype::createStructure(init.vm, init.global);
auto* prototype = BuildMessagePrototype::create(init.vm, init.global, prototypeStructure);
JSC::FunctionPrototype* functionPrototype = init.global->functionPrototype();
auto* constructorStructure = JSBuildMessageConstructor::createStructure(init.vm, init.global, functionPrototype);
auto* constructor = JSBuildMessageConstructor::create(init.vm, constructorStructure, prototype);
auto* structure = JSC::ErrorInstance::createStructure(init.vm, init.global, prototype);
init.setPrototype(prototype);
init.setStructure(structure);
init.setConstructor(constructor);
}
// Main toJS function called from Zig
extern "C" JSC::EncodedJSValue BuildMessage__toJS(void* buildMessage, JSC::JSGlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
auto* zigGlobalObject = defaultGlobalObject(globalObject);
// Get the message for the error
BunString messageString = BuildMessage__getMessageString(buildMessage);
WTF::String message = messageString.transferToWTFString();
// Get or create the structure using the lazy class structure
JSC::Structure* structure = zigGlobalObject->m_JSBuildMessageClassStructure.get(zigGlobalObject);
// Create the ErrorInstance with our custom structure
// Pass false for useCurrentFrame to avoid capturing bundler internal stack frames
JSC::ErrorInstance* errorInstance = JSC::ErrorInstance::create(
vm, structure, message, {}, nullptr,
JSC::RuntimeType::TypeNothing, JSC::ErrorType::Error, false);
errorInstance->setBunErrorData(buildMessage);
return JSC::JSValue::encode(errorInstance);
}
} // namespace Bun

View File

@@ -0,0 +1,17 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/JSGlobalObject.h>
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/LazyClassStructure.h>
namespace Bun {
void setupJSBuildMessageClassStructure(JSC::LazyClassStructure::Initializer& init);
} // namespace Bun
// These are called from Zig
extern "C" {
JSC::EncodedJSValue BuildMessage__toJS(void* buildMessage, JSC::JSGlobalObject* globalObject);
}

View File

@@ -0,0 +1,27 @@
#include "JSBuildMessageConstructor.h"
#include "JSBuildMessage.h"
#include <JavaScriptCore/JSCJSValueInlines.h>
using namespace JSC;
namespace Bun {
const JSC::ClassInfo JSBuildMessageConstructor::s_info = { "BuildMessage"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBuildMessageConstructor) };
JSC_DEFINE_HOST_FUNCTION(callBuildMessage, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
VM& vm = lexicalGlobalObject->vm();
ThrowScope scope = DECLARE_THROW_SCOPE(vm);
throwConstructorCannotBeCalledAsFunctionTypeError(lexicalGlobalObject, scope, "BuildMessage"_s);
return {};
}
JSC_DEFINE_HOST_FUNCTION(constructBuildMessage, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = lexicalGlobalObject->vm();
ThrowScope scope = DECLARE_THROW_SCOPE(vm);
throwTypeError(lexicalGlobalObject, scope, "BuildMessage cannot be constructed directly"_s);
return {};
}
} // namespace Bun

View File

@@ -0,0 +1,49 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/InternalFunction.h>
namespace Bun {
JSC_DECLARE_HOST_FUNCTION(callBuildMessage);
JSC_DECLARE_HOST_FUNCTION(constructBuildMessage);
class JSBuildMessageConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSBuildMessageConstructor* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* prototype)
{
JSBuildMessageConstructor* constructor = new (NotNull, JSC::allocateCell<JSBuildMessageConstructor>(vm)) JSBuildMessageConstructor(vm, structure);
constructor->finishCreation(vm, prototype);
return constructor;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.internalFunctionSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
}
private:
JSBuildMessageConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, callBuildMessage, constructBuildMessage)
{
}
void finishCreation(JSC::VM& vm, JSC::JSObject* prototype)
{
Base::finishCreation(vm, 0, "BuildMessage"_s);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
}
};
} // namespace Bun

View File

@@ -0,0 +1,256 @@
#include "root.h"
#include <JavaScriptCore/ObjectConstructor.h>
#include <JavaScriptCore/ErrorInstance.h>
#include <JavaScriptCore/ErrorInstanceInlines.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/FunctionPrototype.h>
#include "JSResolveMessage.h"
#include "JSResolveMessageConstructor.h"
#include "ZigGlobalObject.h"
#include "BunClientData.h"
#include "WebCoreJSBuiltins.h"
#include <JavaScriptCore/PropertySlot.h>
namespace Bun {
// Forward declaration - ResolveMessage is defined in Zig
typedef void ResolveMessage;
extern "C" void* ResolveMessage__fromJS(JSC::EncodedJSValue value);
// External Zig functions
extern "C" BunString ResolveMessage__getMessageString(void* resolveMessage);
extern "C" JSC::EncodedJSValue ResolveMessage__getCode(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getLevel(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getReferrer(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getSpecifier(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getImportKind(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getPosition(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getLine(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__getColumn(void* resolveMessage, JSC::JSGlobalObject*);
extern "C" JSC::EncodedJSValue ResolveMessage__toString(void* resolveMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" JSC::EncodedJSValue ResolveMessage__toJSON(void* resolveMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" JSC::EncodedJSValue ResolveMessage__toPrimitive(void* resolveMessage, JSC::JSGlobalObject*, JSC::CallFrame*);
extern "C" void ResolveMessage__finalize(void* resolveMessage);
// External functions to unwrap tagged pointer
extern "C" void* Bun__getResolveMessage(void* taggedPtr);
// Custom getter definitions
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_code, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getCode(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_level, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getLevel(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_referrer, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getReferrer(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_specifier, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getSpecifier(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_importKind, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getImportKind(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_position, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getPosition(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_line, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getLine(resolveMessage, globalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsResolveMessageGetter_column, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName))
{
auto* resolveMessage = ResolveMessage__fromJS(thisValue);
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__getColumn(resolveMessage, globalObject);
}
// Function implementations
JSC_DEFINE_HOST_FUNCTION(jsResolveMessageFunction_toString, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* resolveMessage = ResolveMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__toString(resolveMessage, globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(jsResolveMessageFunction_toJSON, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* resolveMessage = ResolveMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__toJSON(resolveMessage, globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(jsResolveMessageFunction_toPrimitive, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto* resolveMessage = ResolveMessage__fromJS(JSValue::encode(callFrame->thisValue()));
if (!resolveMessage)
return JSC::JSValue::encode(jsUndefined());
return ResolveMessage__toPrimitive(resolveMessage, globalObject, callFrame);
}
// HashTable for prototype properties
static const HashTableValue ResolveMessagePrototypeValues[] = {
{ "code"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_code, 0 } },
{ "level"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_level, 0 } },
{ "referrer"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_referrer, 0 } },
{ "specifier"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_specifier, 0 } },
{ "importKind"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_importKind, 0 } },
{ "position"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_position, 0 } },
{ "line"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_line, 0 } },
{ "column"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsResolveMessageGetter_column, 0 } },
{ "toString"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsResolveMessageFunction_toString, 0 } },
{ "toJSON"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsResolveMessageFunction_toJSON, 0 } },
};
// Prototype class definition
class ResolveMessagePrototype : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static constexpr unsigned StructureFlags = Base::StructureFlags;
DECLARE_INFO;
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
// Set prototype to ErrorPrototype
return Structure::create(vm, globalObject, globalObject->errorPrototype(), TypeInfo(ObjectType, StructureFlags), info());
}
static ResolveMessagePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
{
ResolveMessagePrototype* prototype = new (NotNull, JSC::allocateCell<ResolveMessagePrototype>(vm)) ResolveMessagePrototype(vm, structure);
prototype->finishCreation(vm, globalObject);
return prototype;
}
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(ResolveMessagePrototype, Base);
return &vm.plainObjectSpace();
}
void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, ResolveMessagePrototype::info(), ResolveMessagePrototypeValues, *this);
// Add name property
this->putDirect(vm, vm.propertyNames->name, JSC::jsString(vm, String("ResolveMessage"_s)), PropertyAttribute::DontEnum | 0);
// Add @@toPrimitive
this->putDirect(vm, vm.propertyNames->toPrimitiveSymbol,
JSC::JSFunction::create(vm, globalObject, 1, String(), jsResolveMessageFunction_toPrimitive, ImplementationVisibility::Private),
PropertyAttribute::DontEnum | 0);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
ResolveMessagePrototype(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure)
{
}
};
const ClassInfo ResolveMessagePrototype::s_info = {
"ResolveMessage"_s,
&Base::s_info,
nullptr,
nullptr,
CREATE_METHOD_TABLE(ResolveMessagePrototype)
};
void setupJSResolveMessageClassStructure(JSC::LazyClassStructure::Initializer& init)
{
auto* prototypeStructure = ResolveMessagePrototype::createStructure(init.vm, init.global);
auto* prototype = ResolveMessagePrototype::create(init.vm, init.global, prototypeStructure);
JSC::FunctionPrototype* functionPrototype = init.global->functionPrototype();
auto* constructorStructure = JSResolveMessageConstructor::createStructure(init.vm, init.global, functionPrototype);
auto* constructor = JSResolveMessageConstructor::create(init.vm, constructorStructure, prototype);
auto* structure = JSC::ErrorInstance::createStructure(init.vm, init.global, prototype);
init.setPrototype(prototype);
init.setStructure(structure);
init.setConstructor(constructor);
}
// Note: Bun__errorInstance__finalize is implemented in ZigGlobalObject.cpp
// to handle both ResolveMessage and BuildMessage with proper TaggedPointerUnion checking
// Main toJS function called from Zig
extern "C" JSC::EncodedJSValue ResolveMessage__toJS(void* resolveMessage, JSC::JSGlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
auto* zigGlobalObject = defaultGlobalObject(globalObject);
// Get the message for the error
BunString messageString = ResolveMessage__getMessageString(resolveMessage);
WTF::String message = messageString.transferToWTFString();
// Get or create the structure using the lazy class structure
JSC::Structure* structure = zigGlobalObject->m_JSResolveMessageClassStructure.get(zigGlobalObject);
// Create the ErrorInstance with our custom structure
// Pass false for useCurrentFrame to avoid capturing bundler internal stack frames
JSC::ErrorInstance* errorInstance = JSC::ErrorInstance::create(
vm, structure, message, {}, nullptr,
JSC::RuntimeType::TypeNothing, JSC::ErrorType::Error, false);
// Create tagged pointer and set it as bunErrorData
errorInstance->setBunErrorData(resolveMessage);
return JSC::JSValue::encode(errorInstance);
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/JSGlobalObject.h>
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/LazyClassStructure.h>
namespace Bun {
void setupJSResolveMessageClassStructure(JSC::LazyClassStructure::Initializer& init);
} // namespace Bun
// These are called from Zig
extern "C" {
JSC::EncodedJSValue ResolveMessage__toJS(void* resolveMessage, JSC::JSGlobalObject* globalObject);
}

View File

@@ -0,0 +1,27 @@
#include "JSResolveMessageConstructor.h"
#include "JSResolveMessage.h"
#include <JavaScriptCore/JSCJSValueInlines.h>
using namespace JSC;
namespace Bun {
const JSC::ClassInfo JSResolveMessageConstructor::s_info = { "ResolveMessage"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSResolveMessageConstructor) };
JSC_DEFINE_HOST_FUNCTION(callResolveMessage, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
VM& vm = lexicalGlobalObject->vm();
ThrowScope scope = DECLARE_THROW_SCOPE(vm);
throwConstructorCannotBeCalledAsFunctionTypeError(lexicalGlobalObject, scope, "ResolveMessage"_s);
return {};
}
JSC_DEFINE_HOST_FUNCTION(constructResolveMessage, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = lexicalGlobalObject->vm();
ThrowScope scope = DECLARE_THROW_SCOPE(vm);
throwTypeError(lexicalGlobalObject, scope, "ResolveMessage cannot be constructed directly"_s);
return {};
}
} // namespace Bun

View File

@@ -0,0 +1,49 @@
#pragma once
#include "root.h"
#include <JavaScriptCore/InternalFunction.h>
namespace Bun {
JSC_DECLARE_HOST_FUNCTION(callResolveMessage);
JSC_DECLARE_HOST_FUNCTION(constructResolveMessage);
class JSResolveMessageConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSResolveMessageConstructor* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* prototype)
{
JSResolveMessageConstructor* constructor = new (NotNull, JSC::allocateCell<JSResolveMessageConstructor>(vm)) JSResolveMessageConstructor(vm, structure);
constructor->finishCreation(vm, prototype);
return constructor;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.internalFunctionSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
}
private:
JSResolveMessageConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, callResolveMessage, constructResolveMessage)
{
}
void finishCreation(JSC::VM& vm, JSC::JSObject* prototype)
{
Base::finishCreation(vm, 0, "ResolveMessage"_s);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
}
};
} // namespace Bun

View File

@@ -63,6 +63,7 @@ pub const JSValue = enum(i64) {
}
extern fn JSC__JSValue__getDirectIndex(JSValue, *JSGlobalObject, u32) JSValue;
pub fn getDirectIndex(this: JSValue, globalThis: *JSGlobalObject, i: u32) JSValue {
return JSC__JSValue__getDirectIndex(this, globalThis, i);
}

View File

@@ -74,6 +74,8 @@
#include "IDLTypes.h"
#include "ImportMetaObject.h"
#include "JS2Native.h"
#include "JSBuildMessage.h"
#include "JSResolveMessage.h"
#include "JSAbortAlgorithm.h"
#include "JSAbortController.h"
#include "JSAbortSignal.h"
@@ -770,25 +772,84 @@ static JSValue computeErrorInfoWithPrepareStackTrace(JSC::VM& vm, Zig::GlobalObj
RELEASE_AND_RETURN(scope, formatStackTraceToJSValue(vm, globalObject, lexicalGlobalObject, errorObject, callSitesArray, prepareStackTrace));
}
static String computeErrorInfoToString(JSC::VM& vm, Vector<StackFrame>& stackTrace, OrdinalNumber& line, OrdinalNumber& column, String& sourceURL)
{
// Zig functions to extract location from BunErrorData and create synthetic stack frames
extern "C" void* Bun__getBuildMessage(void* bunErrorData);
extern "C" void* Bun__getResolveMessage(void* bunErrorData);
extern "C" void BuildMessage__createSyntheticStackFrame(void* buildMessage, ZigStackFrame* frame);
extern "C" void ResolveMessage__createSyntheticStackFrame(void* resolveMessage, ZigStackFrame* frame);
static String computeErrorInfoToString(JSC::VM& vm, Vector<StackFrame>& stackTrace, OrdinalNumber& line, OrdinalNumber& column, String& sourceURL, void* bunErrorData = nullptr)
{
Zig::GlobalObject* globalObject = nullptr;
JSC::JSGlobalObject* lexicalGlobalObject = nullptr;
// If this is a BuildMessage or ResolveMessage, replace any existing stack with synthetic location
// The captured stack will be from bundler internals, not user code
if (bunErrorData != nullptr) {
void* buildMessage = Bun__getBuildMessage(bunErrorData);
void* resolveMessage = Bun__getResolveMessage(bunErrorData);
if (buildMessage != nullptr || resolveMessage != nullptr) {
ZigStackFrame syntheticFrame = {};
if (buildMessage) {
BuildMessage__createSyntheticStackFrame(buildMessage, &syntheticFrame);
} else {
ResolveMessage__createSyntheticStackFrame(resolveMessage, &syntheticFrame);
}
if (!syntheticFrame.source_url.isEmpty()) {
sourceURL = syntheticFrame.source_url.toWTFString();
// ZigStackFrame position fields are stored as zero-based, convert to one-based
line = OrdinalNumber::fromOneBasedInt(syntheticFrame.position.line_zero_based + 1);
column = OrdinalNumber::fromOneBasedInt(syntheticFrame.position.column_zero_based + 1);
syntheticFrame.source_url.deref();
}
}
}
return computeErrorInfoWithoutPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, nullptr);
}
static JSValue computeErrorInfoToJSValueWithoutSkipping(JSC::VM& vm, Vector<StackFrame>& stackTrace, OrdinalNumber& line, OrdinalNumber& column, String& sourceURL, JSObject* errorInstance, void* bunErrorData)
{
UNUSED_PARAM(bunErrorData);
Zig::GlobalObject* globalObject = nullptr;
JSC::JSGlobalObject* lexicalGlobalObject = nullptr;
lexicalGlobalObject = errorInstance->globalObject();
globalObject = jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
// If this is a BuildMessage or ResolveMessage, replace any existing stack with synthetic location
// The captured stack will be from bundler internals, not user code
if (bunErrorData != nullptr) {
void* buildMessage = Bun__getBuildMessage(bunErrorData);
void* resolveMessage = Bun__getResolveMessage(bunErrorData);
if (buildMessage != nullptr || resolveMessage != nullptr) {
// Create a synthetic ZigStackFrame with the correct source location
ZigStackFrame syntheticFrame = {};
if (buildMessage) {
BuildMessage__createSyntheticStackFrame(buildMessage, &syntheticFrame);
} else {
ResolveMessage__createSyntheticStackFrame(resolveMessage, &syntheticFrame);
}
// Only add the frame if it has valid location data
if (!syntheticFrame.source_url.isEmpty()) {
// Create a JSC StackFrame from the synthetic frame
// We need to create a minimal StackFrame that will be formatted correctly
// For now, just update the sourceURL and line/column parameters
// which will be used by formatStackTrace
sourceURL = syntheticFrame.source_url.toWTFString();
// ZigStackFrame position fields are stored as zero-based, convert to one-based
line = OrdinalNumber::fromOneBasedInt(syntheticFrame.position.line_zero_based + 1);
column = OrdinalNumber::fromOneBasedInt(syntheticFrame.position.column_zero_based + 1);
// Clean up the synthetic frame
syntheticFrame.source_url.deref();
}
}
}
// Error.prepareStackTrace - https://v8.dev/docs/stack-trace-api#customizing-stack-traces
if (!globalObject) {
// node:vm will use a different JSGlobalObject
@@ -831,13 +892,11 @@ static JSValue computeErrorInfoToJSValue(JSC::VM& vm, Vector<StackFrame>& stackT
static String computeErrorInfoWrapperToString(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned int& line_in, unsigned int& column_in, String& sourceURL, void* bunErrorData)
{
UNUSED_PARAM(bunErrorData);
OrdinalNumber line = OrdinalNumber::fromOneBasedInt(line_in);
OrdinalNumber column = OrdinalNumber::fromOneBasedInt(column_in);
auto scope = DECLARE_CATCH_SCOPE(vm);
WTF::String result = computeErrorInfoToString(vm, stackTrace, line, column, sourceURL);
WTF::String result = computeErrorInfoToString(vm, stackTrace, line, column, sourceURL, bunErrorData);
if (scope.exception()) {
// TODO: is this correct? vm.setOnComputeErrorInfo doesnt appear to properly handle a function that can throw
// test/js/node/test/parallel/test-stream-writable-write-writev-finish.js is the one that trips the exception checker
@@ -2946,6 +3005,16 @@ void GlobalObject::finishCreation(VM& vm)
init.vm, static_cast<Zig::GlobalObject*>(init.owner)));
});
m_JSBuildMessageClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
Bun::setupJSBuildMessageClassStructure(init);
});
m_JSResolveMessageClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
Bun::setupJSResolveMessageClassStructure(init);
});
m_errorConstructorPrepareStackTraceInternalValue.initLater(
[](const Initializer<JSFunction>& init) {
init.set(JSFunction::create(init.vm, init.owner, 2, "ErrorPrepareStackTrace"_s, jsFunctionDefaultErrorPrepareStackTrace, ImplementationVisibility::Public));

View File

@@ -518,6 +518,8 @@ public:
V(public, JSC::LazyClassStructure, m_JSStatFSClassStructure) \
V(public, JSC::LazyClassStructure, m_JSStatFSBigIntClassStructure) \
V(public, JSC::LazyClassStructure, m_JSDirentClassStructure) \
V(public, JSC::LazyClassStructure, m_JSBuildMessageClassStructure) \
V(public, JSC::LazyClassStructure, m_JSResolveMessageClassStructure) \
\
V(private, WebCore::JSBuiltinInternalFunctions, m_builtinInternalFunctions) \
V(private, std::unique_ptr<WebCore::DOMConstructors>, m_constructors) \

View File

@@ -33,19 +33,17 @@
Blob GlobalObject::m_JSBlob ClassStructure
Buffer GlobalObject::m_JSBufferClassStructure ClassStructure
BuildError GlobalObject::m_JSBuildMessage ClassStructure
BuildMessage GlobalObject::m_JSBuildMessage ClassStructure
Crypto GlobalObject::m_JSCrypto ClassStructure
HTMLRewriter GlobalObject::m_JSHTMLRewriter ClassStructure
Request GlobalObject::m_JSRequest ClassStructure
ResolveError GlobalObject::m_JSResolveMessage ClassStructure
ResolveMessage GlobalObject::m_JSResolveMessage ClassStructure
Response GlobalObject::m_JSResponse ClassStructure
TextDecoder GlobalObject::m_JSTextDecoder ClassStructure
AbortController AbortControllerConstructorCallback PropertyCallback
AbortSignal AbortSignalConstructorCallback PropertyCallback
BroadcastChannel BroadcastChannelConstructorCallback PropertyCallback
BuildError GlobalObject::m_JSBuildMessageClassStructure ClassStructure
BuildMessage GlobalObject::m_JSBuildMessageClassStructure ClassStructure
ByteLengthQueuingStrategy ByteLengthQueuingStrategyConstructorCallback PropertyCallback
CloseEvent CloseEventConstructorCallback PropertyCallback
CountQueuingStrategy CountQueuingStrategyConstructorCallback PropertyCallback
@@ -75,6 +73,8 @@
ReadableStreamBYOBRequest ReadableStreamBYOBRequestConstructorCallback PropertyCallback
ReadableStreamDefaultController ReadableStreamDefaultControllerConstructorCallback PropertyCallback
ReadableStreamDefaultReader ReadableStreamDefaultReaderConstructorCallback PropertyCallback
ResolveError GlobalObject::m_JSResolveMessageClassStructure ClassStructure
ResolveMessage GlobalObject::m_JSResolveMessageClassStructure ClassStructure
SubtleCrypto SubtleCryptoConstructorCallback PropertyCallback
TextDecoderStream TextDecoderStreamConstructorCallback PropertyCallback
TextEncoder TextEncoderConstructorCallback PropertyCallback

View File

@@ -11,11 +11,11 @@
#include <JavaScriptCore/AsyncFunctionPrototype.h>
#include <JavaScriptCore/CallFrame.h>
#include <JavaScriptCore/CallFrameInlines.h>
#include <JavaScriptCore/ErrorInstance.h>
#include <JavaScriptCore/ErrorPrototype.h>
#include <JavaScriptCore/GeneratorFunctionPrototype.h>
#include <JavaScriptCore/JSArrayBuffer.h>
#include <JavaScriptCore/ObjectConstructor.h>
#include "ZigGeneratedClasses.h"
#include "JSKeyObject.h"
#include "NodeUtilTypesModule.h"
@@ -155,13 +155,6 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsNativeError,
JSCell* cell = value.asCell();
if (cell->type() == ErrorInstanceType)
return JSValue::encode(jsBoolean(true));
// Workaround for https://github.com/oven-sh/bun/issues/11780
// They have code that does
// assert(util.types.isNativeError(resolveMessage))
// FIXME: delete this once ResolveMessage and BuildMessage extend Error
if (cell->inherits<WebCore::JSResolveMessage>() || cell->inherits<WebCore::JSBuildMessage>())
return JSValue::encode(jsBoolean(true));
}
return JSValue::encode(jsBoolean(false));

View File

@@ -1,118 +0,0 @@
import { define } from "../codegen/class-definitions";
export default [
define({
name: "ResolveMessage",
construct: true,
finalize: true,
configurable: false,
klass: {},
JSType: "0b11101110",
proto: {
message: {
getter: "getMessage",
cache: true,
writable: true,
},
code: {
getter: "getCode",
cache: true,
},
name: {
value: "ResolveMessage",
},
level: {
getter: "getLevel",
cache: true,
},
referrer: {
getter: "getReferrer",
cache: true,
},
specifier: {
getter: "getSpecifier",
cache: true,
},
importKind: {
getter: "getImportKind",
cache: true,
},
position: {
getter: "getPosition",
cache: true,
},
line: {
getter: "getLine",
},
column: {
getter: "getColumn",
},
["@@toPrimitive"]: {
fn: "toPrimitive",
length: 1,
},
["toString"]: {
fn: "toString",
length: 0,
},
["toJSON"]: {
fn: "toJSON",
length: 0,
},
},
}),
define({
name: "BuildMessage",
construct: true,
finalize: true,
configurable: false,
klass: {},
JSType: "0b11101110",
proto: {
message: {
getter: "getMessage",
cache: true,
writable: true,
},
name: {
value: "BuildMessage",
},
level: {
getter: "getLevel",
cache: true,
},
position: {
getter: "getPosition",
cache: true,
},
notes: {
getter: "getNotes",
cache: true,
},
line: {
getter: "getLine",
},
column: {
getter: "getColumn",
},
["@@toPrimitive"]: {
fn: "toPrimitive",
length: 1,
},
["toString"]: {
fn: "toString",
length: 0,
},
["toJSON"]: {
fn: "toJSON",
length: 0,
},
},
}),
];