diff options
-rw-r--r-- | .github/workflows/bun-linux-aarch64.yml | 2 | ||||
-rw-r--r-- | .github/workflows/bun-linux-build.yml | 4 | ||||
-rw-r--r-- | .github/workflows/bun-mac-aarch64.yml | 16 | ||||
-rw-r--r-- | .github/workflows/bun-mac-x64-baseline.yml | 16 | ||||
-rw-r--r-- | .github/workflows/bun-mac-x64.yml | 16 | ||||
-rw-r--r-- | Dockerfile | 2 | ||||
-rwxr-xr-x | bun.lockb | bin | 72925 -> 72925 bytes | |||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 188 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 28 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 22 | ||||
-rw-r--r-- | test/js/node/v8/capture-stack-trace.test.js | 12 |
12 files changed, 241 insertions, 67 deletions
diff --git a/.github/workflows/bun-linux-aarch64.yml b/.github/workflows/bun-linux-aarch64.yml index 9bee835b7..01714460b 100644 --- a/.github/workflows/bun-linux-aarch64.yml +++ b/.github/workflows/bun-linux-aarch64.yml @@ -36,7 +36,7 @@ jobs: arch: aarch64 build_arch: arm64 runner: linux-arm64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-arm64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-linux-arm64-lto.tar.gz" webkit_basename: "bun-webkit-linux-arm64-lto" build_machine_arch: aarch64 diff --git a/.github/workflows/bun-linux-build.yml b/.github/workflows/bun-linux-build.yml index 8689d488e..798ffaf33 100644 --- a/.github/workflows/bun-linux-build.yml +++ b/.github/workflows/bun-linux-build.yml @@ -46,7 +46,7 @@ jobs: arch: x86_64 build_arch: amd64 runner: big-ubuntu - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-linux-amd64-lto.tar.gz" webkit_basename: "bun-webkit-linux-amd64-lto" build_machine_arch: x86_64 - cpu: nehalem @@ -54,7 +54,7 @@ jobs: arch: x86_64 build_arch: amd64 runner: big-ubuntu - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-linux-amd64-lto.tar.gz" webkit_basename: "bun-webkit-linux-amd64-lto" build_machine_arch: x86_64 diff --git a/.github/workflows/bun-mac-aarch64.yml b/.github/workflows/bun-mac-aarch64.yml index 3040eee43..f281783bd 100644 --- a/.github/workflows/bun-mac-aarch64.yml +++ b/.github/workflows/bun-mac-aarch64.yml @@ -117,7 +117,7 @@ jobs: # obj: bun-obj-darwin-x64-baseline # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: true # compile_obj: false # - cpu: haswell @@ -126,7 +126,7 @@ jobs: # obj: bun-obj-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: true # compile_obj: false # - cpu: nehalem @@ -135,7 +135,7 @@ jobs: # obj: bun-obj-darwin-x64-baseline # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: false # compile_obj: true # - cpu: haswell @@ -144,7 +144,7 @@ jobs: # obj: bun-obj-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: false # compile_obj: true - cpu: native @@ -152,7 +152,7 @@ jobs: tag: bun-darwin-aarch64 obj: bun-obj-darwin-aarch64 artifact: bun-obj-darwin-aarch64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-arm64-lto.tar.gz" runner: macos-arm64 dependencies: true compile_obj: true @@ -257,7 +257,7 @@ jobs: # package: bun-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # - cpu: haswell # arch: x86_64 # tag: bun-darwin-x64 @@ -265,14 +265,14 @@ jobs: # package: bun-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" - cpu: native arch: aarch64 tag: bun-darwin-aarch64 obj: bun-obj-darwin-aarch64 package: bun-darwin-aarch64 artifact: bun-obj-darwin-aarch64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-arm64-lto.tar.gz" runner: macos-arm64 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/bun-mac-x64-baseline.yml b/.github/workflows/bun-mac-x64-baseline.yml index dea617b21..b5f79a757 100644 --- a/.github/workflows/bun-mac-x64-baseline.yml +++ b/.github/workflows/bun-mac-x64-baseline.yml @@ -117,7 +117,7 @@ jobs: obj: bun-obj-darwin-x64-baseline runner: macos-11 artifact: bun-obj-darwin-x64-baseline - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" dependencies: true compile_obj: false # - cpu: haswell @@ -126,7 +126,7 @@ jobs: # obj: bun-obj-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: true # compile_obj: false - cpu: nehalem @@ -135,7 +135,7 @@ jobs: obj: bun-obj-darwin-x64-baseline runner: macos-11 artifact: bun-obj-darwin-x64-baseline - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" dependencies: false compile_obj: true # - cpu: haswell @@ -144,7 +144,7 @@ jobs: # obj: bun-obj-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: false # compile_obj: true # - cpu: native @@ -152,7 +152,7 @@ jobs: # tag: bun-darwin-aarch64 # obj: bun-obj-darwin-aarch64 # artifact: bun-obj-darwin-aarch64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # runner: macos-arm64 # dependencies: true # compile_obj: true @@ -258,7 +258,7 @@ jobs: package: bun-darwin-x64 runner: macos-11 artifact: bun-obj-darwin-x64-baseline - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # - cpu: haswell # arch: x86_64 # tag: bun-darwin-x64 @@ -266,14 +266,14 @@ jobs: # package: bun-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # - cpu: native # arch: aarch64 # tag: bun-darwin-aarch64 # obj: bun-obj-darwin-aarch64 # package: bun-darwin-aarch64 # artifact: bun-obj-darwin-aarch64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # runner: macos-arm64 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/bun-mac-x64.yml b/.github/workflows/bun-mac-x64.yml index 2f2143ab1..8b30321f0 100644 --- a/.github/workflows/bun-mac-x64.yml +++ b/.github/workflows/bun-mac-x64.yml @@ -117,7 +117,7 @@ jobs: # obj: bun-obj-darwin-x64-baseline # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: true # compile_obj: false - cpu: haswell @@ -126,7 +126,7 @@ jobs: obj: bun-obj-darwin-x64 runner: macos-11 artifact: bun-obj-darwin-x64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" dependencies: true compile_obj: false # - cpu: nehalem @@ -135,7 +135,7 @@ jobs: # obj: bun-obj-darwin-x64-baseline # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # dependencies: false # compile_obj: true - cpu: haswell @@ -144,7 +144,7 @@ jobs: obj: bun-obj-darwin-x64 runner: macos-11 artifact: bun-obj-darwin-x64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" dependencies: false compile_obj: true # - cpu: native @@ -152,7 +152,7 @@ jobs: # tag: bun-darwin-aarch64 # obj: bun-obj-darwin-aarch64 # artifact: bun-obj-darwin-aarch64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-arm64-lto.tar.gz" # runner: macos-arm64 # dependencies: true # compile_obj: true @@ -260,7 +260,7 @@ jobs: # package: bun-darwin-x64 # runner: macos-11 # artifact: bun-obj-darwin-x64-baseline - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" - cpu: haswell arch: x86_64 tag: bun-darwin-x64 @@ -268,14 +268,14 @@ jobs: package: bun-darwin-x64 runner: macos-11 artifact: bun-obj-darwin-x64 - webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz" + webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-amd64-lto.tar.gz" # - cpu: native # arch: aarch64 # tag: bun-darwin-aarch64 # obj: bun-obj-darwin-aarch64 # package: bun-darwin-aarch64 # artifact: bun-obj-darwin-aarch64 - # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz" + # webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-2/bun-webkit-macos-arm64-lto.tar.gz" # runner: macos-arm64 steps: - uses: actions/checkout@v3 diff --git a/Dockerfile b/Dockerfile index b4a76208f..f50ada2d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ARG ARCH=x86_64 ARG BUILD_MACHINE_ARCH=x86_64 ARG TRIPLET=${ARCH}-linux-gnu ARG BUILDARCH=amd64 -ARG WEBKIT_TAG=may20-1 +ARG WEBKIT_TAG=may20-2 ARG ZIG_TAG=jul1 ARG ZIG_VERSION="0.11.0-dev.3737+9eb008717" ARG WEBKIT_BASENAME="bun-webkit-linux-$BUILDARCH" Binary files differdiff --git a/package.json b/package.json index 94f9968ea..4fe213747 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@types/react": "^18.0.25", "@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/parser": "^5.31.0", - "bun-webkit": "0.0.1-4b3750ddfe644a5bb131d652407653fac528ad51" + "bun-webkit": "0.0.1-8a03cf746abef8a48c932ab25f8821390632f2e2" }, "version": "0.0.0", "prettier": "./.prettierrc.cjs" diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index b27e0aafc..4b4edf097 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -219,7 +219,9 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c JSC::Options::useJITCage() = false; JSC::Options::useShadowRealm() = true; JSC::Options::useResizableArrayBuffer() = true; +#ifdef BUN_DEBUG JSC::Options::showPrivateScriptsInStackTraces() = true; +#endif JSC::Options::useSetMethods() = true; /* @@ -312,6 +314,123 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c } extern "C" void* Bun__getVM(); +extern "C" JSGlobalObject* Bun__getDefaultGlobal(); + +static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorInstance) +{ + if (!errorInstance) { + return String(); + } + + Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(errorInstance->globalObject()); + if (!globalObject) { + // Happens in node:vm + globalObject = jsDynamicCast<Zig::GlobalObject*>(Bun__getDefaultGlobal()); + } + + WTF::String name = "Error"_s; + WTF::String message; + + if (errorInstance) { + // Note that we are not allowed to allocate memory in here. It's called inside a finalizer. + if (auto* instance = jsDynamicCast<ErrorInstance*>(errorInstance)) { + name = instance->sanitizedNameString(globalObject); + message = instance->sanitizedMessageString(globalObject); + } + } + + WTF::StringBuilder sb; + + if (!name.isEmpty()) { + sb.append(name); + sb.append(": "_s); + } + + if (!message.isEmpty()) { + sb.append(message); + } + + if (stackTrace.isEmpty()) { + return sb.toString(); + } + + if ((!message.isEmpty() || !name.isEmpty())) { + sb.append("\n"_s); + } + + size_t framesCount = stackTrace.size(); + ZigStackFrame remappedFrames[framesCount]; + bool hasSet = false; + for (size_t i = 0; i < framesCount; i++) { + StackFrame& frame = stackTrace.at(i); + + sb.append(" at "_s); + + WTF::String functionName = frame.functionName(vm); + + if (auto codeblock = frame.codeBlock()) { + if (codeblock->isConstructor()) { + sb.append("new "_s); + } + + // TODO: async + } + + if (functionName.isEmpty()) { + sb.append("<anonymous>"_s); + } else { + sb.append(functionName); + } + + sb.append(" ("_s); + + if (frame.hasLineAndColumnInfo()) { + unsigned int thisLine = 0; + unsigned int thisColumn = 0; + frame.computeLineAndColumn(thisLine, thisColumn); + remappedFrames[i].position.line = thisLine; + remappedFrames[i].position.column_start = thisColumn; + remappedFrames[i].source_url = Zig::toZigString(frame.sourceURL(vm)); + + // This ensures the lifetime of the sourceURL is accounted for correctly + Bun__remapStackFramePositions(globalObject, remappedFrames + i, 1); + + if (!hasSet) { + hasSet = true; + line = thisLine; + column = thisColumn; + sourceURL = frame.sourceURL(vm); + + if (errorInstance) { + if (remappedFrames[i].remapped) { + errorInstance->putDirect(vm, Identifier::fromString(vm, "originalLine"_s), jsNumber(thisLine), 0); + errorInstance->putDirect(vm, Identifier::fromString(vm, "originalColumn"_s), jsNumber(thisColumn), 0); + } + } + } + + sb.append(frame.sourceURL(vm)); + sb.append(":"_s); + sb.append(remappedFrames[i].position.line); + sb.append(":"_s); + sb.append(remappedFrames[i].position.column_start); + } else { + sb.append("native"_s); + } + sb.append(")"_s); + + if (i != framesCount - 1) { + sb.append("\n"_s); + } + } + + return sb.toString(); +} + +static String computeErrorInfo(JSC::VM& vm, Vector<StackFrame>& stackTrace, unsigned& line, unsigned& column, String& sourceURL, JSObject* errorInstance) +{ + return computeErrorInfoWithoutPrepareStackTrace(vm, stackTrace, line, column, sourceURL, errorInstance); +} extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObjectClass, int count, void* console_client) @@ -329,6 +448,9 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(JSClassRef* globalObje Zig::GlobalObject* globalObject = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::JSGlobalObject::create(vm, JSC::JSGlobalObject::createStructure(vm, JSC::jsNull())), JSC::jsNull())); globalObject->setConsole(globalObject); globalObject->isThreadLocalDefaultGlobalObject = true; + globalObject->setStackTraceLimit(DEFAULT_ERROR_STACK_TRACE_LIMIT); // Node.js defaults to 10 + vm.setOnComputeErrorInfo(computeErrorInfo); + if (count > 0) { globalObject->installAPIGlobals(globalObjectClass, count, vm); } @@ -2585,7 +2707,32 @@ JSC::JSValue GlobalObject::formatStackTrace(JSC::VM& vm, JSC::JSGlobalObject* le extern "C" EncodedJSValue JSPasswordObject__create(JSC::JSGlobalObject*, bool); -JSC_DECLARE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace); +JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncAppendStackTrace, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject); + JSC::VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSC::ErrorInstance* source = jsDynamicCast<JSC::ErrorInstance*>(callFrame->argument(0)); + JSC::ErrorInstance* destination = jsDynamicCast<JSC::ErrorInstance*>(callFrame->argument(1)); + + if (!source || !destination) { + throwTypeError(lexicalGlobalObject, scope, "First & second argument must be an Error object"_s); + return JSC::JSValue::encode(jsUndefined()); + } + + if (!destination->stackTrace()) { + destination->captureStackTrace(vm, globalObject, 1); + } + + if (source->stackTrace()) { + destination->stackTrace()->appendVector(*source->stackTrace()); + source->stackTrace()->clear(); + } + + return JSC::JSValue::encode(jsUndefined()); +} + JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) { GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject); @@ -2600,18 +2747,15 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb JSC::JSObject* errorObject = objectArg.asCell()->getObject(); JSC::JSValue caller = callFrame->argument(1); + // We cannot use our ErrorInstance::captureStackTrace() fast path here unfortunately. + // We need to return these CallSite array objects which means we need to create them JSValue errorValue = lexicalGlobalObject->get(lexicalGlobalObject, vm.propertyNames->Error); auto* errorConstructor = jsDynamicCast<JSC::JSObject*>(errorValue); - - size_t stackTraceLimit = DEFAULT_ERROR_STACK_TRACE_LIMIT; - if (JSC::JSValue stackTraceLimitProp = errorConstructor->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->stackTraceLimit)) { - if (stackTraceLimitProp.isNumber()) { - stackTraceLimit = std::min(std::max(static_cast<size_t>(stackTraceLimitProp.toIntegerOrInfinity(lexicalGlobalObject)), 0ul), 2048ul); - if (stackTraceLimit == 0) { - stackTraceLimit = 2048; - } - } + size_t stackTraceLimit = globalObject->stackTraceLimit().value(); + if (stackTraceLimit == 0) { + stackTraceLimit = DEFAULT_ERROR_STACK_TRACE_LIMIT; } + JSCStackTrace stackTrace = JSCStackTrace::captureCurrentJSStackTrace(globalObject, callFrame, stackTraceLimit, caller); // Create an (uninitialized) array for our "call sites" @@ -2672,9 +2816,20 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb errorObject->deleteProperty(lexicalGlobalObject, vm.propertyNames->stack); } if (formattedStackTrace.isUndefinedOrNull()) { - errorObject->putDirect(vm, vm.propertyNames->stack, jsUndefined(), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); - } else { - errorObject->putDirect(vm, vm.propertyNames->stack, formattedStackTrace, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + formattedStackTrace = JSC::jsUndefined(); + } + + errorObject->putDirect(vm, vm.propertyNames->stack, formattedStackTrace, 0); + + if (!(caller && caller.isObject())) { + if (auto* instance = jsDynamicCast<JSC::ErrorInstance*>(errorObject)) { + // we make a separate copy of the StackTrace unfortunately so that we + // can later console.log it without losing the info + // + // This is not good. We should remove this in the future as it strictly makes this function + // already slower than necessary. + instance->captureStackTrace(vm, globalObject, 1, false); + } } RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSValue {})); @@ -3118,11 +3273,8 @@ void GlobalObject::finishCreation(VM& vm) RELEASE_ASSERT(classInfo()); JSC::JSObject* errorConstructor = this->errorConstructor(); - errorConstructor->putDirectNativeFunctionWithoutTransition(vm, this, JSC::Identifier::fromString(vm, "captureStackTrace"_s), 2, errorConstructorFuncCaptureStackTrace, ImplementationVisibility::Public, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0); - - // JSC default is 100 - errorConstructor->putDirect(vm, vm.propertyNames->stackTraceLimit, jsNumber(DEFAULT_ERROR_STACK_TRACE_LIMIT), JSC::PropertyAttribute::DontEnum | 0); - + errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "captureStackTrace"_s), 2, errorConstructorFuncCaptureStackTrace, ImplementationVisibility::Public, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0); + errorConstructor->putDirectNativeFunction(vm, this, JSC::Identifier::fromString(vm, "appendStackTrace"_s), 2, errorConstructorFuncAppendStackTrace, ImplementationVisibility::Private, JSC::NoIntrinsic, PropertyAttribute::DontEnum | 0); JSC::JSValue console = this->get(this, JSC::Identifier::fromString(vm, "console"_s)); JSC::JSObject* consoleObject = console.getObject(); consoleObject->putDirectBuiltinFunction(vm, this, vm.propertyNames->asyncIteratorSymbol, consoleObjectAsyncIteratorCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete); diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 3f3d82dc4..68aef29dd 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -3528,12 +3528,13 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, JSC::JSValue val) { JSC::JSObject* obj = JSC::jsDynamicCast<JSC::JSObject*>(val); + JSC::VM& vm = global->vm(); bool getFromSourceURL = false; if (stackTrace != nullptr && stackTrace->size() > 0) { - populateStackTrace(global->vm(), *stackTrace, &except->stack); + populateStackTrace(vm, *stackTrace, &except->stack); } else if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) { - populateStackTrace(global->vm(), *err->stackTrace(), &except->stack); + populateStackTrace(vm, *err->stackTrace(), &except->stack); } else { getFromSourceURL = true; } @@ -3546,7 +3547,7 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, } if (except->code == SYNTAX_ERROR_CODE) { except->message = Zig::toZigString(err->sanitizedMessageString(global)); - } else if (JSC::JSValue message = obj->getIfPropertyExists(global, global->vm().propertyNames->message)) { + } else if (JSC::JSValue message = obj->getIfPropertyExists(global, vm.propertyNames->message)) { except->message = Zig::toZigString(message, global); @@ -3556,7 +3557,7 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, except->name = Zig::toZigString(err->sanitizedNameString(global)); except->runtime_type = err->runtimeTypeForCause(); - auto clientData = WebCore::clientData(global->vm()); + auto clientData = WebCore::clientData(vm); if (except->code != SYNTAX_ERROR_CODE) { if (JSC::JSValue syscall = obj->getIfPropertyExists(global, clientData->builtinNames().syscallPublicName())) { @@ -3571,7 +3572,7 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, except->path = Zig::toZigString(path, global); } - if (JSC::JSValue fd = obj->getIfPropertyExists(global, Identifier::fromString(global->vm(), "fd"_s))) { + if (JSC::JSValue fd = obj->getIfPropertyExists(global, Identifier::fromString(vm, "fd"_s))) { if (fd.isAnyInt()) { except->fd = fd.toInt32(global); } @@ -3583,17 +3584,17 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, } if (getFromSourceURL) { - if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, global->vm().propertyNames->sourceURL)) { + if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, vm.propertyNames->sourceURL)) { except->stack.frames_ptr[0].source_url = Zig::toZigString(sourceURL, global); - if (JSC::JSValue column = obj->getIfPropertyExists(global, global->vm().propertyNames->column)) { + if (JSC::JSValue column = obj->getIfPropertyExists(global, vm.propertyNames->column)) { except->stack.frames_ptr[0].position.column_start = column.toInt32(global); } - if (JSC::JSValue line = obj->getIfPropertyExists(global, global->vm().propertyNames->line)) { + if (JSC::JSValue line = obj->getIfPropertyExists(global, vm.propertyNames->line)) { except->stack.frames_ptr[0].position.line = line.toInt32(global); - if (JSC::JSValue lineText = obj->getIfPropertyExists(global, JSC::Identifier::fromString(global->vm(), "lineText"_s))) { + if (JSC::JSValue lineText = obj->getIfPropertyExists(global, JSC::Identifier::fromString(vm, "lineText"_s))) { if (JSC::JSString* jsStr = lineText.toStringOrNull(global)) { auto str = jsStr->value(global); except->stack.source_lines_ptr[0] = Zig::toZigString(str); @@ -3603,7 +3604,9 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, } } } + except->stack.frames_len = 1; + except->stack.frames_ptr[0].remapped = obj->hasProperty(global, JSC::Identifier::fromString(vm, "originalLine"_s)); } } @@ -3654,7 +3657,12 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal if (JSC::JSValue line = obj->getIfPropertyExists(global, global->vm().propertyNames->line)) { if (line) { - except->stack.frames_ptr[0].position.line = line.toInt32(global); + // TODO: don't sourcemap it twice + if (auto originalLine = obj->getIfPropertyExists(global, JSC::Identifier::fromString(global->vm(), "originalLine"_s))) { + except->stack.frames_ptr[0].position.line = originalLine.toInt32(global); + } else { + except->stack.frames_ptr[0].position.line = line.toInt32(global); + } except->stack.frames_len = 1; } } diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index cb1a50f1d..5c58eff60 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1981,19 +1981,21 @@ pub const VirtualMachine = struct { } pub fn remapStackFramePositions(this: *VirtualMachine, frames: [*]JSC.ZigStackFrame, frames_count: usize) void { - var i: usize = 0; - while (i < frames_count) : (i += 1) { - if (frames[i].position.isInvalid()) continue; + for (frames[0..frames_count]) |*frame| { + if (frame.position.isInvalid() or frame.remapped) continue; + var sourceURL = frame.source_url.toSlice(bun.default_allocator); + defer sourceURL.deinit(); + if (this.source_mappings.resolveMapping( - frames[i].source_url.slice(), - @max(frames[i].position.line, 0), - @max(frames[i].position.column_start, 0), + sourceURL.slice(), + @max(frame.position.line, 0), + @max(frame.position.column_start, 0), )) |mapping| { - frames[i].position.line = mapping.original.lines; - frames[i].position.column_start = mapping.original.columns; - frames[i].remapped = true; + frame.position.line = mapping.original.lines; + frame.position.column_start = mapping.original.columns; + frame.remapped = true; } else { - frames[i].remapped = true; + frame.remapped = true; } } } diff --git a/test/js/node/v8/capture-stack-trace.test.js b/test/js/node/v8/capture-stack-trace.test.js index d96f91483..cb2624681 100644 --- a/test/js/node/v8/capture-stack-trace.test.js +++ b/test/js/node/v8/capture-stack-trace.test.js @@ -5,6 +5,18 @@ afterEach(() => { Error.prepareStackTrace = origPrepareStackTrace; }); +test("Regular .stack", () => { + var err; + class Foo { + constructor() { + err = new Error("wat"); + } + } + + new Foo(); + expect(err.stack).toMatch(/at new Foo/); +}); + test("capture stack trace", () => { function f1() { f2(); |