Skip to content
Open
3 changes: 3 additions & 0 deletions src/ast/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2847,6 +2847,9 @@ impl Source {
col: u64,
) -> Option<usize> {
use bun_core::strings::{CodepointIterator, Cursor};
if line == start_line && col == start_col {
return Some(0);
}
let iter_ = CodepointIterator::init(source_contents);
let mut iter = Cursor::default();

Expand Down
46 changes: 26 additions & 20 deletions src/runtime/bake/BakeSourceProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "JavaScriptCore/JSModuleRecord.h"
#include "JavaScriptCore/JSString.h"
#include "JavaScriptCore/JSModuleNamespaceObject.h"
#include "JavaScriptCore/ParserError.h"
#include "ImportMetaObject.h"
#include <wtf/text/MakeString.h>

Expand Down Expand Up @@ -81,26 +82,30 @@ extern "C" JSC::EncodedJSValue BakeLoadModuleByKey(JSC::JSGlobalObject* global,
return JSC::JSValue::encode(promise);
}

extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatch(GlobalObject* global, BunString source) {
JSC::VM&vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

String string = "bake://server.patch.js"_s;
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
JSC::SourceCode sourceCode = JSC::SourceCode(SourceProvider::create(
global,
source.transferToWTFString(),
origin,
WTF::move(string),
WTF::TextPosition(),
JSC::SourceProviderSourceType::Program
));

JSC::JSValue result = vm.interpreter.executeProgram(sourceCode, global, global);
RETURN_IF_EXCEPTION(scope, {});
// Returns true when JSC's parser rejects `source`. `errorLine` and `errorColumn` are then 0-based.
extern "C" bool BakeFindServerCodeSyntaxError(JSC::JSGlobalObject* global, BunString source, uint32_t* errorLine, uint32_t* errorColumn, BunString* errorMessage) {
auto& vm = JSC::getVM(global);
JSC::SourceCode sourceCode = JSC::makeSource(source.transferToWTFString(), JSC::SourceOrigin(), JSC::SourceTaintedOrigin::Untainted);

JSC::ParserError error;
if (JSC::checkSyntax(vm, sourceCode, error)) return false;

String message;
if (error.type() == JSC::ParserError::SyntaxError) {
message = error.message();
} else if (error.type() == JSC::ParserError::StackOverflow) {
// The parser gives this one no message.
message = "Maximum call stack size exceeded."_s;
} else {
return false;
}

RELEASE_ASSERT(result);
return JSC::JSValue::encode(result);
int offset = error.token().m_startPosition.offset;
JSC::LineColumn position = sourceCode.provider()->lineColumnInTextForOffset(offset < 0 ? 0 : offset);
*errorLine = position.line;
*errorColumn = position.column;
*errorMessage = Bun::toStringRef(message);
return true;
}

extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatchWithSourceMap(GlobalObject* global, BunString source, const char* sourceMapJSONPtr, size_t sourceMapJSONLength) {
Expand All @@ -112,7 +117,6 @@ extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatchWithSourceMap(GlobalObject*

// Use DevServerSourceProvider with the source map JSON
auto provider = DevServerSourceProvider::create(
global,
source.transferToWTFString(),
sourceMapJSONPtr,
sourceMapJSONLength,
Expand All @@ -128,6 +132,8 @@ extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatchWithSourceMap(GlobalObject*
RETURN_IF_EXCEPTION(scope, {});

RELEASE_ASSERT(result);
// A chunk that did not load must not take the source map of the code that runs.
provider->registerSourceMap(global);
return JSC::JSValue::encode(result);
}

Expand Down
20 changes: 11 additions & 9 deletions src/runtime/bake/DevServerSourceProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ extern "C" void Bun__removeDevServerSourceProvider(void* bun_vm, DevServerSource
class DevServerSourceProvider final : public JSC::StringSourceProvider {
public:
static Ref<DevServerSourceProvider> create(
JSC::JSGlobalObject* globalObject,
const String& source,
const char* sourceMapJSONPtr,
size_t sourceMapJSONLength,
Expand All @@ -25,13 +24,16 @@ class DevServerSourceProvider final : public JSC::StringSourceProvider {
const TextPosition& startPosition,
JSC::SourceProviderSourceType sourceType)
{
auto provider = adoptRef(*new DevServerSourceProvider(source, sourceMapJSONPtr, sourceMapJSONLength, sourceOrigin, WTF::move(sourceURL), startPosition, sourceType));
auto* zigGlobalObject = uncheckedDowncast<::Zig::GlobalObject>(globalObject);
auto specifier = Bun::toString(provider->sourceURL());
provider->m_bunVM = zigGlobalObject->bunVM();
provider->m_specifier = specifier;
Bun__addDevServerSourceProvider(provider->m_bunVM, provider.ptr(), &specifier);
return provider;
return adoptRef(*new DevServerSourceProvider(source, sourceMapJSONPtr, sourceMapJSONLength, sourceOrigin, WTF::move(sourceURL), startPosition, sourceType));
}

// Stack traces then remap through this provider. It takes the place of the provider that had the same URL.
void registerSourceMap(JSC::JSGlobalObject* globalObject)
{
ASSERT(!m_bunVM);
m_bunVM = uncheckedDowncast<::Zig::GlobalObject>(globalObject)->bunVM();
m_specifier = Bun::toString(sourceURL());
Bun__addDevServerSourceProvider(m_bunVM, this, &m_specifier);
}

MiCString sourceMapJSON() const
Expand Down Expand Up @@ -67,7 +69,7 @@ class DevServerSourceProvider final : public JSC::StringSourceProvider {
}

MiString m_sourceMapJSON;
// The Rust VirtualMachine, captured at creation. Not the GC-allocated
// The Rust VirtualMachine, captured by registerSourceMap. Not the GC-allocated
// Zig::GlobalObject: this destructor runs from JSC sweep, by which point
// the global object cell may already have been swept.
void* m_bunVM { nullptr };
Expand Down
Loading
Loading