aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Ashcon Partovi <ashcon@partovi.net> 2023-08-03 15:31:55 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-03 15:31:55 -0700
commit08cf0d562ae81b4fb30aa5e599ca76056582ac5f (patch)
tree8385fce04c9bf7b4138ae3c3545aa330f388f456 /src/bun.js
parent9a2c3dea88b22351ecc85126b0c225bfefea71bf (diff)
downloadbun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.tar.gz
bun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.tar.zst
bun-08cf0d562ae81b4fb30aa5e599ca76056582ac5f.zip
Bunch of fixes (#3516)
* Fix #3497 * Fix #3497 * Run prettier * Fix package.json * remove this too * yeah * Fix missing tests * Use native for utf-8-validate * Add module ID names to builtins * Defer evaluation of ESM & CJS modules until link time * Use builtin name for exports in plugins * Add module IDs to builtins * Update JSC build with new flag * WebKit upgrade fixes * Update WebKit * prettier * Upgrade WebKit * bump * Update once again * Add visitAdditionalChildren, remove .fill() usage * Update process.test.js * Update fs.test.ts --------- Co-authored-by: dave caruso <me@paperdave.net> Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js')
m---------src/bun.js/WebKit0
-rw-r--r--src/bun.js/bindings/InternalModuleRegistry.cpp65
-rw-r--r--src/bun.js/bindings/ModuleLoader.cpp30
-rw-r--r--src/bun.js/bindings/sqlite/JSSQLStatement.cpp137
-rw-r--r--src/bun.js/bindings/webcore/HTTPParsers.cpp8
-rw-r--r--src/bun.js/bindings/webcore/ParsedContentType.cpp8
-rw-r--r--src/bun.js/module_loader.zig4
-rw-r--r--src/bun.js/modules/BunJSCModule.h8
-rw-r--r--src/bun.js/modules/UTF8ValidateModule.h20
-rw-r--r--src/bun.js/modules/_NativeModule.h3
10 files changed, 166 insertions, 117 deletions
diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit
-Subproject 284095ff91529df883cf5ab30d66048a3207bad
+Subproject 9d9172d3242b40f16fa980ead750dc9ab248065
diff --git a/src/bun.js/bindings/InternalModuleRegistry.cpp b/src/bun.js/bindings/InternalModuleRegistry.cpp
index 552e9fbfe..e6b574d7b 100644
--- a/src/bun.js/bindings/InternalModuleRegistry.cpp
+++ b/src/bun.js/bindings/InternalModuleRegistry.cpp
@@ -16,33 +16,34 @@ namespace Bun {
// JS builtin that acts as a module. In debug mode, we use a different implementation that reads
// from the developer's filesystem. This allows reloading code without recompiling bindings.
-#define INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleName) \
- auto throwScope = DECLARE_THROW_SCOPE(vm); \
- \
- SourceCode source = JSC::makeSource(SOURCE, SourceOrigin(WTF::URL("builtin://" #moduleName ".js"_s)), #moduleName ".js"_s); \
- \
- JSFunction* func \
- = JSFunction::create( \
- vm, \
- createBuiltinExecutable( \
- vm, source, \
- Identifier(), \
- ImplementationVisibility::Public, \
- ConstructorKind::None, \
- ConstructAbility::CannotConstruct) \
- ->link(vm, nullptr, source), \
- static_cast<JSC::JSGlobalObject*>(globalObject)); \
- \
- JSC::MarkedArgumentBuffer argList; \
- \
- JSValue result = JSC::call( \
- globalObject, \
- func, \
- JSC::getCallData(func), \
- globalObject, JSC::MarkedArgumentBuffer()); \
- \
- RETURN_IF_EXCEPTION(throwScope, {}); \
- ASSERT_INTERNAL_MODULE(result, moduleName); \
+#define INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleName) \
+ auto throwScope = DECLARE_THROW_SCOPE(vm); \
+ auto&& origin = SourceOrigin(WTF::URL(makeString("builtin://"_s, moduleName))); \
+ SourceCode source = JSC::makeSource(SOURCE, origin, moduleName); \
+ \
+ JSFunction* func \
+ = JSFunction::create( \
+ vm, \
+ createBuiltinExecutable( \
+ vm, source, \
+ Identifier(), \
+ ImplementationVisibility::Public, \
+ ConstructorKind::None, \
+ ConstructAbility::CannotConstruct) \
+ ->link(vm, nullptr, source), \
+ static_cast<JSC::JSGlobalObject*>(globalObject)); \
+ \
+ RETURN_IF_EXCEPTION(throwScope, {}); \
+ \
+ JSC::MarkedArgumentBuffer argList; \
+ JSValue result = JSC::call( \
+ globalObject, \
+ func, \
+ JSC::getCallData(func), \
+ globalObject, JSC::MarkedArgumentBuffer()); \
+ \
+ RETURN_IF_EXCEPTION(throwScope, {}); \
+ ASSERT_INTERNAL_MODULE(result, moduleName); \
return result;
#if BUN_DEBUG
@@ -129,11 +130,15 @@ JSValue InternalModuleRegistry::requireId(JSGlobalObject* globalObject, VM& vm,
// so we want to write it to the internal field when loaded.
JSC_DEFINE_HOST_FUNCTION(InternalModuleRegistry::jsCreateInternalModuleById, (JSGlobalObject * lexicalGlobalObject, CallFrame* callframe))
{
+ auto& vm = lexicalGlobalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
auto id = callframe->argument(0).toUInt32(lexicalGlobalObject);
+
auto registry = static_cast<Zig::GlobalObject*>(lexicalGlobalObject)->internalModuleRegistry();
- auto module = registry->createInternalModuleById(lexicalGlobalObject, lexicalGlobalObject->vm(), static_cast<Field>(id));
- registry->internalField(static_cast<Field>(id)).set(lexicalGlobalObject->vm(), registry, module);
- return JSValue::encode(module);
+ auto mod = registry->createInternalModuleById(lexicalGlobalObject, vm, static_cast<Field>(id));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ registry->internalField(static_cast<Field>(id)).set(vm, registry, mod);
+ return JSValue::encode(mod);
}
} // namespace Bun
diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp
index 2e4dfa88e..2c8b95612 100644
--- a/src/bun.js/bindings/ModuleLoader.cpp
+++ b/src/bun.js/bindings/ModuleLoader.cpp
@@ -65,19 +65,25 @@ static JSC::JSInternalPromise* resolvedInternalPromise(JSC::JSGlobalObject* glob
}
// Converts an object from InternalModuleRegistry into { ...obj, default: obj }
-JSC::SyntheticSourceProvider::SyntheticSourceGenerator
-generateInternalModuleSourceCode(JSC::JSGlobalObject* globalObject, JSC::JSObject* object)
+static JSC::SyntheticSourceProvider::SyntheticSourceGenerator
+generateInternalModuleSourceCode(JSC::JSGlobalObject* globalObject, InternalModuleRegistry::Field moduleId)
{
- return [object](JSC::JSGlobalObject* lexicalGlobalObject,
+ return [moduleId](JSC::JSGlobalObject* lexicalGlobalObject,
JSC::Identifier moduleKey,
Vector<JSC::Identifier, 4>& exportNames,
JSC::MarkedArgumentBuffer& exportValues) -> void {
JSC::VM& vm = lexicalGlobalObject->vm();
- GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject);
- JSC::EnsureStillAliveScope stillAlive(object);
-
+ GlobalObject* globalObject = jsCast<GlobalObject*>(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* object = jsCast<JSObject*>(globalObject->internalModuleRegistry()->requireId(globalObject, vm, moduleId));
+ if (!object) {
+ return;
+ }
+ RETURN_IF_EXCEPTION(throwScope, {});
+
+ JSC::EnsureStillAliveScope stillAlive(object);
+
PropertyNameArray properties(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
object->getPropertyNames(globalObject, properties, DontEnumPropertiesMode::Exclude);
@@ -102,7 +108,8 @@ static OnLoadResult handleOnLoadObjectResult(Zig::GlobalObject* globalObject, JS
OnLoadResult result {};
result.type = OnLoadResultTypeObject;
JSC::VM& vm = globalObject->vm();
- if (JSC::JSValue exportsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "exports"_s))) {
+ auto& builtinNames = WebCore::builtinNames(vm);
+ if (JSC::JSValue exportsValue = object->getIfPropertyExists(globalObject, builtinNames.exportsPublicName())) {
if (exportsValue.isObject()) {
result.value.object = exportsValue;
return result;
@@ -436,12 +443,14 @@ JSValue fetchCommonJSModule(
default: {
if (tag & SyntheticModuleType::InternalModuleRegistryFlag) {
constexpr auto mask = (SyntheticModuleType::InternalModuleRegistryFlag - 1);
+ auto result = globalObject->internalModuleRegistry()->requireId(globalObject, vm, static_cast<InternalModuleRegistry::Field>(tag & mask));
+ RETURN_IF_EXCEPTION(scope, {});
+
target->putDirect(
vm,
builtinNames.exportsPublicName(),
- globalObject->internalModuleRegistry()->requireId(globalObject, vm, static_cast<InternalModuleRegistry::Field>(tag & mask)),
+ result,
JSC::PropertyAttribute::ReadOnly | 0);
- RETURN_IF_EXCEPTION(scope, {});
RELEASE_AND_RETURN(scope, target);
} else {
RELEASE_AND_RETURN(scope, jsNumber(-1));
@@ -592,8 +601,7 @@ static JSValue fetchESMSourceCode(
default: {
if (tag & SyntheticModuleType::InternalModuleRegistryFlag) {
constexpr auto mask = (SyntheticModuleType::InternalModuleRegistryFlag - 1);
- auto* internalModule = jsCast<JSObject*>(globalObject->internalModuleRegistry()->requireId(globalObject, vm, static_cast<InternalModuleRegistry::Field>(tag & mask)));
- auto source = JSC::SourceCode(JSC::SyntheticSourceProvider::create(generateInternalModuleSourceCode(globalObject, internalModule), JSC::SourceOrigin(), WTFMove(moduleKey)));
+ auto source = JSC::SourceCode(JSC::SyntheticSourceProvider::create(generateInternalModuleSourceCode(globalObject, static_cast<InternalModuleRegistry::Field>(tag & mask)), JSC::SourceOrigin(URL(makeString("builtins://", moduleKey))), moduleKey));
return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source)));
} else {
auto&& provider = Zig::SourceProvider::create(globalObject, res->result.value, JSC::SourceProviderSourceType::Module, true);
diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
index b177a1b6f..d42f01019 100644
--- a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
+++ b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp
@@ -175,6 +175,8 @@ public:
}
DECLARE_VISIT_CHILDREN;
DECLARE_EXPORT_INFO;
+ template<typename Visitor> void visitAdditionalChildren(Visitor&);
+ template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
// static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
@@ -263,6 +265,8 @@ static void initializeColumnNames(JSC::JSGlobalObject* lexicalGlobalObject, JSSQ
if (LIKELY(!anyHoles)) {
Structure* structure = globalObject.structureCache().emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), columnNames->size());
+ vm.writeBarrier(castedThis, structure);
+
for (const auto& propertyName : *columnNames) {
structure = Structure::addPropertyTransition(vm, structure, propertyName, 0, offset);
}
@@ -423,8 +427,10 @@ static JSC::JSValue rebindObject(JSC::JSGlobalObject* globalObject, JSC::JSValue
JSValue value;
if (LIKELY(!slot.isTaintedByOpaqueObject()))
value = slot.getValue(globalObject, propertyName);
- else
+ else {
value = target->get(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, JSValue());
+ }
// Ensure this gets freed on scope clear
auto utf8 = WTF::String(propertyName.string()).utf8();
@@ -1075,76 +1081,57 @@ static inline JSC::JSValue constructResultObject(JSC::JSGlobalObject* lexicalGlo
auto* stmt = castedThis->stmt;
if (auto* structure = castedThis->_structure.get()) {
- RELEASE_ASSERT(count <= 64);
- // It looks a little silly doing these two loops right?
- //
- // The code that does putDirectOffset has to be very careful about time between GC allocations
- // while the object is not fully initialized.
- //
- // So we do two loops
- // 1. The first loop to fill all the values from SQLite into a MarkedVector.
- // 2. The second loop to actually put them into the object.
-
- // This rowBuffer is a stack allocation.
- MarkedVector<JSValue, 64> rowBuffer;
-
- rowBuffer.fill(count, [&](JSValue* value) -> void {
- // Loop 1. Fill the rowBuffer with values from SQLite
- for (int i = 0; i < count; i++, value++) {
- switch (sqlite3_column_type(stmt, i)) {
- case SQLITE_INTEGER: {
- // https://github.com/oven-sh/bun/issues/1536
- *value = jsNumber(sqlite3_column_int64(stmt, i));
- break;
- }
- case SQLITE_FLOAT: {
- *value = jsNumber(sqlite3_column_double(stmt, i));
- break;
- }
- // > Note that the SQLITE_TEXT constant was also used in SQLite version
- // > 2 for a completely different meaning. Software that links against
- // > both SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT,
- // > not SQLITE_TEXT.
- case SQLITE3_TEXT: {
- size_t len = sqlite3_column_bytes(stmt, i);
- const unsigned char* text = len > 0 ? sqlite3_column_text(stmt, i) : nullptr;
-
- if (len > 64) {
- *value = JSC::JSValue::decode(Bun__encoding__toStringUTF8(text, len, lexicalGlobalObject));
- continue;
- }
-
- *value = jsString(vm, WTF::String::fromUTF8(text, len));
- break;
- }
- case SQLITE_BLOB: {
- size_t len = sqlite3_column_bytes(stmt, i);
- const void* blob = len > 0 ? sqlite3_column_blob(stmt, i) : nullptr;
- JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), len);
+ result = JSC::constructEmptyObject(vm, structure);
- if (LIKELY(blob && len))
- memcpy(array->vector(), blob, len);
+ for (unsigned int i = 0; i < count; i++) {
+ JSValue value;
- *value = array;
- break;
- }
- default: {
- *value = jsNull();
- break;
- }
+ // Loop 1. Fill the rowBuffer with values from SQLite
+ switch (sqlite3_column_type(stmt, i)) {
+ case SQLITE_INTEGER: {
+ // https://github.com/oven-sh/bun/issues/1536
+ value = jsNumber(sqlite3_column_int64(stmt, i));
+ break;
+ }
+ case SQLITE_FLOAT: {
+ value = jsNumber(sqlite3_column_double(stmt, i));
+ break;
+ }
+ // > Note that the SQLITE_TEXT constant was also used in SQLite version
+ // > 2 for a completely different meaning. Software that links against
+ // > both SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT,
+ // > not SQLITE_TEXT.
+ case SQLITE3_TEXT: {
+ size_t len = sqlite3_column_bytes(stmt, i);
+ const unsigned char* text = len > 0 ? sqlite3_column_text(stmt, i) : nullptr;
+
+ if (len > 64) {
+ value = JSC::JSValue::decode(Bun__encoding__toStringUTF8(text, len, lexicalGlobalObject));
+ continue;
}
+
+ value = jsString(vm, WTF::String::fromUTF8(text, len));
+ break;
}
- });
+ case SQLITE_BLOB: {
+ size_t len = sqlite3_column_bytes(stmt, i);
+ const void* blob = len > 0 ? sqlite3_column_blob(stmt, i) : nullptr;
+ JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), len);
- result = JSC::constructEmptyObject(vm, structure);
+ if (LIKELY(blob && len))
+ memcpy(array->vector(), blob, len);
- // TODO: Add .forEach to MarkedVector<>. When JSC assertions are enabled, this function will fail.
- rowBuffer.fill(count, [&](JSValue* value) -> void {
- // Loop 2. fill the rowBuffer with values from SQLite
- for (unsigned int i = 0; i < count; i++, value++) {
- result->putDirectOffset(vm, i, *value);
+ value = array;
+ break;
+ }
+ default: {
+ value = jsNull();
+ break;
}
- });
+ }
+
+ result->putDirectOffset(vm, i, value);
+ }
} else {
if (count <= 64) {
@@ -1697,4 +1684,26 @@ void JSSQLStatement::visitChildrenImpl(JSCell* cell, Visitor& visitor)
}
DEFINE_VISIT_CHILDREN(JSSQLStatement);
+
+template<typename Visitor>
+void JSSQLStatement::visitAdditionalChildren(Visitor& visitor)
+{
+ JSSQLStatement* thisObject = this;
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+ visitor.append(thisObject->_structure);
+ visitor.append(thisObject->_prototype);
+}
+
+template<typename Visitor>
+void JSSQLStatement::visitOutputConstraints(JSCell* cell, Visitor& visitor)
+{
+ auto* thisObject = jsCast<JSSQLStatement*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitOutputConstraints(thisObject, visitor);
+ thisObject->visitAdditionalChildren(visitor);
+}
+
+template void JSSQLStatement::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
+template void JSSQLStatement::visitOutputConstraints(JSCell*, SlotVisitor&);
}
diff --git a/src/bun.js/bindings/webcore/HTTPParsers.cpp b/src/bun.js/bindings/webcore/HTTPParsers.cpp
index f2c4ff989..66aec4925 100644
--- a/src/bun.js/bindings/webcore/HTTPParsers.cpp
+++ b/src/bun.js/bindings/webcore/HTTPParsers.cpp
@@ -543,7 +543,7 @@ XSSProtectionDisposition parseXSSProtectionHeader(const String& header, String&
ContentTypeOptionsDisposition parseContentTypeOptionsHeader(StringView header)
{
StringView leftToken = header.left(header.find(','));
- if (equalLettersIgnoringASCIICase(leftToken.trim(isJSONOrHTTPWhitespace<UChar>), "nosniff"_s))
+ if (equalLettersIgnoringASCIICase(leftToken.trim(isASCIIWhitespaceWithoutFF<UChar>), "nosniff"_s))
return ContentTypeOptionsDisposition::Nosniff;
return ContentTypeOptionsDisposition::None;
}
@@ -602,7 +602,7 @@ XFrameOptionsDisposition parseXFrameOptionsHeader(StringView header)
// return result;
// for (auto value : StringView(headerValue).split(',')) {
-// auto trimmedValue = value.trim(isJSONOrHTTPWhitespace<UChar>);
+// auto trimmedValue = value.trim(isASCIIWhitespaceWithoutFF<UChar>);
// if (trimmedValue == "\"cache\""_s)
// result.add(ClearSiteDataValue::Cache);
// else if (trimmedValue == "\"cookies\""_s)
@@ -632,7 +632,7 @@ bool parseRange(StringView range, RangeAllowWhitespace allowWhitespace, long lon
if (!startsWithLettersIgnoringASCIICase(range, "bytes"_s))
return false;
- auto byteRange = range.substring(bytesLength).trim(isJSONOrHTTPWhitespace<UChar>);
+ auto byteRange = range.substring(bytesLength).trim(isASCIIWhitespaceWithoutFF<UChar>);
if (!byteRange.startsWith('='))
return false;
@@ -962,7 +962,7 @@ bool isSafeMethod(const String& method)
CrossOriginResourcePolicy parseCrossOriginResourcePolicyHeader(StringView header)
{
- auto trimmedHeader = header.trim(isJSONOrHTTPWhitespace<UChar>);
+ auto trimmedHeader = header.trim(isASCIIWhitespaceWithoutFF<UChar>);
if (trimmedHeader.isEmpty())
return CrossOriginResourcePolicy::None;
diff --git a/src/bun.js/bindings/webcore/ParsedContentType.cpp b/src/bun.js/bindings/webcore/ParsedContentType.cpp
index c4773b3ee..38e0f532c 100644
--- a/src/bun.js/bindings/webcore/ParsedContentType.cpp
+++ b/src/bun.js/bindings/webcore/ParsedContentType.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
static void skipSpaces(StringView input, unsigned& startIndex)
{
- while (startIndex < input.length() && isJSONOrHTTPWhitespace(input[startIndex]))
+ while (startIndex < input.length() && isASCIIWhitespaceWithoutFF(input[startIndex]))
++startIndex;
}
@@ -78,7 +78,7 @@ static StringView parseToken(StringView input, unsigned& startIndex, CharacterMe
while (input[tokenEnd - 1] == ' ')
--tokenEnd;
} else {
- while (isJSONOrHTTPWhitespace(input[tokenEnd - 1]))
+ while (isASCIIWhitespaceWithoutFF(input[tokenEnd - 1]))
--tokenEnd;
}
}
@@ -328,7 +328,7 @@ bool ParsedContentType::parseContentType(Mode mode)
std::optional<ParsedContentType> ParsedContentType::create(const String& contentType, Mode mode)
{
- ParsedContentType parsedContentType(mode == Mode::Rfc2045 ? contentType : contentType.trim(isJSONOrHTTPWhitespace<UChar>));
+ ParsedContentType parsedContentType(mode == Mode::Rfc2045 ? contentType : contentType.trim(isASCIIWhitespaceWithoutFF<UChar>));
if (!parsedContentType.parseContentType(mode))
return std::nullopt;
return { WTFMove(parsedContentType) };
@@ -368,7 +368,7 @@ void ParsedContentType::setContentType(String&& contentRange, Mode mode)
{
m_mimeType = WTFMove(contentRange);
if (mode == Mode::MimeSniff)
- m_mimeType = StringView(m_mimeType).trim(isJSONOrHTTPWhitespace<UChar>).convertToASCIILowercase();
+ m_mimeType = StringView(m_mimeType).trim(isASCIIWhitespaceWithoutFF<UChar>).convertToASCIILowercase();
else
m_mimeType = m_mimeType.trim(deprecatedIsSpaceOrNewline);
}
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index 7cc1f4574..d37410131 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -2245,6 +2245,7 @@ pub const ModuleLoader = struct {
.@"isomorphic-fetch" => return jsSyntheticModule(.@"isomorphic-fetch", specifier),
.@"node-fetch" => return jsSyntheticModule(.@"node-fetch", specifier),
.@"@vercel/fetch" => return jsSyntheticModule(.vercel_fetch, specifier),
+ .@"utf-8-validate" => return jsSyntheticModule(.@"utf-8-validate", specifier),
.undici => return jsSyntheticModule(.undici, specifier),
.ws => return jsSyntheticModule(.ws, specifier),
}
@@ -2416,6 +2417,7 @@ pub const HardcodedModule = enum {
@"isomorphic-fetch",
@"node-fetch",
@"@vercel/fetch",
+ @"utf-8-validate",
// These are all not implemented yet, but are stubbed
@"node:v8",
@"node:trace_events",
@@ -2496,6 +2498,7 @@ pub const HardcodedModule = enum {
.{ "undici", HardcodedModule.undici },
.{ "ws", HardcodedModule.ws },
.{ "@vercel/fetch", HardcodedModule.@"@vercel/fetch" },
+ .{ "utf-8-validate", HardcodedModule.@"utf-8-validate" },
},
);
pub const Alias = struct {
@@ -2601,6 +2604,7 @@ pub const HardcodedModule = enum {
.{ "worker_threads", .{ .path = "node:worker_threads" } },
.{ "ws", .{ .path = "ws" } },
.{ "ws/lib/websocket", .{ .path = "ws" } },
+ .{ "utf-8-validate", .{ .path = "utf-8-validate" } },
.{ "zlib", .{ .path = "node:zlib" } },
// .{ "readable-stream", .{ .path = "node:stream" } },
// .{ "readable-stream/consumer", .{ .path = "node:stream/consumers" } },
diff --git a/src/bun.js/modules/BunJSCModule.h b/src/bun.js/modules/BunJSCModule.h
index c5350fcd7..d7548dcdf 100644
--- a/src/bun.js/modules/BunJSCModule.h
+++ b/src/bun.js/modules/BunJSCModule.h
@@ -47,6 +47,7 @@ JSC_DEFINE_HOST_FUNCTION(functionStartRemoteDebugger,
#if ENABLE(REMOTE_INSPECTOR)
static const char *defaultHost = "127.0.0.1\0";
static uint16_t defaultPort = 9230; // node + 1
+
auto &vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -311,7 +312,8 @@ JSC_DEFINE_HOST_FUNCTION(functionSamplingProfilerStackTraces,
globalObject, scope,
createError(globalObject, "Sampling profiler was never started"_s)));
- WTF::String jsonString = vm.samplingProfiler()->stackTracesAsJSON();
+ WTF::String jsonString =
+ vm.samplingProfiler()->stackTracesAsJSON()->toJSONString();
JSC::EncodedJSValue result =
JSC::JSValue::encode(JSONParse(globalObject, jsonString));
scope.releaseAssertNoException();
@@ -519,8 +521,8 @@ JSC_DEFINE_HOST_FUNCTION(functionRunProfiler, (JSGlobalObject * globalObject,
StringPrintStream byteCodes;
samplingProfiler.reportTopBytecodes(byteCodes);
- JSValue stackTraces =
- JSONParse(globalObject, samplingProfiler.stackTracesAsJSON());
+ JSValue stackTraces = JSONParse(
+ globalObject, samplingProfiler.stackTracesAsJSON()->toJSONString());
samplingProfiler.shutdown();
samplingProfiler.clearData();
diff --git a/src/bun.js/modules/UTF8ValidateModule.h b/src/bun.js/modules/UTF8ValidateModule.h
new file mode 100644
index 000000000..18f309e63
--- /dev/null
+++ b/src/bun.js/modules/UTF8ValidateModule.h
@@ -0,0 +1,20 @@
+
+using namespace JSC;
+using namespace WebCore;
+
+namespace Zig {
+inline void
+generateNativeModule_UTF8Validate(JSC::JSGlobalObject *globalObject,
+ JSC::Identifier moduleKey,
+ Vector<JSC::Identifier, 4> &exportNames,
+ JSC::MarkedArgumentBuffer &exportValues) {
+ auto &vm = globalObject->vm();
+
+ exportNames.append(vm.propertyNames->defaultKeyword);
+ exportValues.append(JSC::JSFunction::create(
+ vm, globalObject, 1, "utf8Validate"_s, jsBufferConstructorFunction_isUtf8,
+ ImplementationVisibility::Public, NoIntrinsic,
+ jsBufferConstructorFunction_isUtf8));
+}
+
+} // namespace Zig
diff --git a/src/bun.js/modules/_NativeModule.h b/src/bun.js/modules/_NativeModule.h
index 01a112d0b..96eb9ad9d 100644
--- a/src/bun.js/modules/_NativeModule.h
+++ b/src/bun.js/modules/_NativeModule.h
@@ -31,7 +31,8 @@
macro("node:process"_s, NodeProcess) \
macro("node:string_decoder"_s, NodeStringDecoder) \
macro("node:tty"_s, NodeTTY) \
- macro("node:util/types"_s, NodeUtilTypes) \
+ macro("node:util/types"_s, NodeUtilTypes) \
+ macro("utf-8-validate"_s, UTF8Validate) \
#if ASSERT_ENABLED