Skip to content

Commit

Permalink
Fixes #10588 & upgrade WebKit (#10596)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored Apr 28, 2024
1 parent dfcbe09 commit e58d67b
Show file tree
Hide file tree
Showing 32 changed files with 355 additions and 157 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0067 NEW)

set(Bun_VERSION "1.1.6")
set(WEBKIT_TAG 5fe78270f2efca3c0ee3013259776923053d5011)
set(WEBKIT_TAG f0fbde91399d504266064d8845628bf29a9e834d)

set(BUN_WORKDIR "${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "Configuring Bun ${Bun_VERSION} in ${BUN_WORKDIR}")
Expand Down
25 changes: 4 additions & 21 deletions src/bun.js/bindings/BunObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,25 +355,6 @@ JSC_DEFINE_HOST_FUNCTION(functionBunSleep,
extern "C" JSC::EncodedJSValue Bun__escapeHTML8(JSGlobalObject* globalObject, JSC::EncodedJSValue input, const LChar* ptr, size_t length);
extern "C" JSC::EncodedJSValue Bun__escapeHTML16(JSGlobalObject* globalObject, JSC::EncodedJSValue input, const UChar* ptr, size_t length);

// JSC_DEFINE_JIT_OPERATION(functionBunEscapeHTMLWithoutTypeCheck, JSC::EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, JSObject* castedglobalObject, JSString* string))
// {
// JSC::VM& vm = JSC::getVM(lexicalGlobalObject);
// IGNORE_WARNINGS_BEGIN("frame-address")
// CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
// IGNORE_WARNINGS_END
// JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
// size_t length = string->length();
// if (!length)
// return JSValue::encode(string);

// auto resolvedString = string->value(lexicalGlobalObject);
// if (!resolvedString.is8Bit()) {
// return Bun__escapeHTML16(lexicalGlobalObject, JSValue::encode(string), resolvedString.characters16(), length);
// } else {
// return Bun__escapeHTML8(lexicalGlobalObject, JSValue::encode(string), resolvedString.characters8(), length);
// }
// }

JSC_DEFINE_HOST_FUNCTION(functionBunEscapeHTML, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = JSC::getVM(lexicalGlobalObject);
Expand All @@ -393,9 +374,11 @@ JSC_DEFINE_HOST_FUNCTION(functionBunEscapeHTML, (JSC::JSGlobalObject * lexicalGl
auto resolvedString = string->value(lexicalGlobalObject);
JSC::EncodedJSValue encodedInput = JSValue::encode(string);
if (!resolvedString.is8Bit()) {
RELEASE_AND_RETURN(scope, Bun__escapeHTML16(lexicalGlobalObject, encodedInput, resolvedString.characters16(), length));
const auto span = resolvedString.span16();
RELEASE_AND_RETURN(scope, Bun__escapeHTML16(lexicalGlobalObject, encodedInput, span.data(), span.size()));
} else {
RELEASE_AND_RETURN(scope, Bun__escapeHTML8(lexicalGlobalObject, encodedInput, resolvedString.characters8(), length));
const auto span = resolvedString.span8();
RELEASE_AND_RETURN(scope, Bun__escapeHTML8(lexicalGlobalObject, encodedInput, span.data(), span.size()));
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/bun.js/bindings/BunString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,9 +491,11 @@ size_t BunString::utf8ByteLength(const WTF::String& str)
return 0;

if (str.is8Bit()) {
return simdutf::utf8_length_from_latin1(reinterpret_cast<const char*>(str.characters8()), static_cast<size_t>(str.length()));
const auto s = str.span8();
return simdutf::utf8_length_from_latin1(reinterpret_cast<const char*>(s.data()), static_cast<size_t>(s.size()));
} else {
return simdutf::utf8_length_from_utf16(reinterpret_cast<const char16_t*>(str.characters16()), static_cast<size_t>(str.length()));
const auto s = str.span16();
return simdutf::utf8_length_from_utf16(reinterpret_cast<const char16_t*>(s.data()), static_cast<size_t>(s.size()));
}
}

Expand Down Expand Up @@ -561,10 +563,6 @@ extern "C" bool WTFStringImpl__isThreadSafe(
return false;

return !(wtf->isSymbol() || wtf->isAtom());
// if (wtf->is8Bit())
// return wtf->characters8() == reinterpret_cast_ptr<const LChar*>(reinterpret_cast<const uint8_t*>(wtf) + tailOffset<const LChar*>());

// return wtf->characters16() == reinterpret_cast_ptr<const UChar*>(reinterpret_cast<const uint16_t*>(wtf) + tailOffset<const UChar*>());
}

extern "C" void Bun__WTFStringImpl__ensureHash(WTF::StringImpl* str)
Expand Down
16 changes: 16 additions & 0 deletions src/bun.js/bindings/CallSite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ void CallSite::visitChildrenImpl(JSCell* cell, Visitor& visitor)
visitor.append(thisCallSite->m_functionName);
visitor.append(thisCallSite->m_sourceURL);
}
JSC_DEFINE_HOST_FUNCTION(nativeFrameForTesting, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSC::JSFunction* function = jsCast<JSC::JSFunction*>(callFrame->argument(0));

return JSValue::encode(
JSC::call(globalObject, function, JSC::ArgList(), "nativeFrameForTesting"_s));
}

JSValue createNativeFrameForTesting(Zig::GlobalObject* globalObject)
{
VM& vm = globalObject->vm();

return JSC::JSFunction::create(vm, globalObject, 1, "nativeFrameForTesting"_s, nativeFrameForTesting, ImplementationVisibility::Public);
}

void CallSite::formatAsString(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WTF::StringBuilder& sb)
{
Expand Down
1 change: 1 addition & 0 deletions src/bun.js/bindings/CallSite.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,5 @@ class CallSite final : public JSC::JSNonFinalObject {
DECLARE_VISIT_CHILDREN;
};

JSValue createNativeFrameForTesting(Zig::GlobalObject* globalObject);
}
92 changes: 82 additions & 10 deletions src/bun.js/bindings/ErrorStackTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,37 @@ JSCStackTrace JSCStackTrace::fromExisting(JSC::VM& vm, const WTF::Vector<JSC::St
return JSCStackTrace(newFrames);
}

static bool isImplementationVisibilityPrivate(JSC::StackVisitor& visitor)
{
ImplementationVisibility implementationVisibility = [&]() -> ImplementationVisibility {
if (auto* codeBlock = visitor->codeBlock()) {
if (auto* executable = codeBlock->ownerExecutable()) {
return executable->implementationVisibility();
}
return ImplementationVisibility::Public;
}

#if ENABLE(WEBASSEMBLY)
if (visitor->isNativeCalleeFrame())
return visitor->callee().asNativeCallee()->implementationVisibility();
#endif

if (visitor->callee().isCell()) {
if (auto* callee = visitor->callee().asCell()) {
if (auto* jsFunction = jsDynamicCast<JSFunction*>(callee)) {
if (auto* executable = jsFunction->executable())
return executable->implementationVisibility();
return ImplementationVisibility::Public;
}
}
}

return ImplementationVisibility::Public;
}();

return implementationVisibility != ImplementationVisibility::Public;
}

JSCStackTrace JSCStackTrace::captureCurrentJSStackTrace(Zig::GlobalObject* globalObject, JSC::CallFrame* callFrame, size_t frameLimit, JSC::JSValue caller)
{
JSC::VM& vm = globalObject->vm();
Expand All @@ -63,31 +94,72 @@ JSCStackTrace JSCStackTrace::captureCurrentJSStackTrace(Zig::GlobalObject* globa
callerName = callerFunctionInternal->name();
}

JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus {
// skip caller frame and all frames above it
if (!callerName.isEmpty()) {
if (!callerName.isEmpty()) {
JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus {
if (isImplementationVisibilityPrivate(visitor)) {
return WTF::IterationStatus::Continue;
}

framesCount += 1;

// skip caller frame and all frames above it
if (!belowCaller) {
skipFrames += 1;

if (visitor->functionName() == callerName) {
belowCaller = true;
return WTF::IterationStatus::Continue;
}
}

return WTF::IterationStatus::Continue;
});
} else if (caller && caller.isCell()) {
JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus {
if (isImplementationVisibilityPrivate(visitor)) {
return WTF::IterationStatus::Continue;
}

framesCount += 1;

// skip caller frame and all frames above it
if (!belowCaller) {
auto callee = visitor->callee();
skipFrames += 1;
if (callee.isCell() && callee.asCell() == caller) {
belowCaller = true;
return WTF::IterationStatus::Continue;
}
}
}
if (!visitor->isNativeFrame()) {
framesCount++;
}

return WTF::IterationStatus::Continue;
});
return WTF::IterationStatus::Continue;
});
} else if (caller.isEmpty() || caller.isUndefined()) {
// Skip the first frame.
JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus {
if (isImplementationVisibilityPrivate(visitor)) {
return WTF::IterationStatus::Continue;
}

framesCount += 1;

if (!belowCaller) {
skipFrames += 1;
belowCaller = true;
}

return WTF::IterationStatus::Continue;
});
}

framesCount = std::min(frameLimit, framesCount);

// Create the actual stack frames
size_t i = 0;
stackFrames.reserveInitialCapacity(framesCount);
JSC::StackVisitor::visit(callFrame, vm, [&](JSC::StackVisitor& visitor) -> WTF::IterationStatus {
// Skip native frames
if (visitor->isNativeFrame()) {
if (isImplementationVisibilityPrivate(visitor)) {
return WTF::IterationStatus::Continue;
}

Expand Down
34 changes: 22 additions & 12 deletions src/bun.js/bindings/JSBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,11 @@ static inline JSC::EncodedJSValue writeToBuffer(JSC::JSGlobalObject* lexicalGlob
case WebCore::BufferEncodingType::hex: {

if (view.is8Bit()) {
written = Bun__encoding__writeLatin1(view.characters8(), view.length(), reinterpret_cast<unsigned char*>(castedThis->vector()) + offset, length, static_cast<uint8_t>(encoding));
const auto span = view.span8();
written = Bun__encoding__writeLatin1(span.data(), span.size(), reinterpret_cast<unsigned char*>(castedThis->vector()) + offset, length, static_cast<uint8_t>(encoding));
} else {
written = Bun__encoding__writeUTF16(view.characters16(), view.length(), reinterpret_cast<unsigned char*>(castedThis->vector()) + offset, length, static_cast<uint8_t>(encoding));
const auto span = view.span16();
written = Bun__encoding__writeUTF16(span.data(), span.size(), reinterpret_cast<unsigned char*>(castedThis->vector()) + offset, length, static_cast<uint8_t>(encoding));
}
break;
}
Expand Down Expand Up @@ -373,19 +375,22 @@ static JSC::EncodedJSValue constructFromEncoding(JSGlobalObject* lexicalGlobalOb
JSC::EncodedJSValue result;

if (view.is8Bit()) {
const auto span = view.span8();

switch (encoding) {
case WebCore::BufferEncodingType::utf8:
case WebCore::BufferEncodingType::ucs2:
case WebCore::BufferEncodingType::utf16le:
case WebCore::BufferEncodingType::base64:
case WebCore::BufferEncodingType::base64url:
case WebCore::BufferEncodingType::hex: {
result = Bun__encoding__constructFromLatin1(lexicalGlobalObject, view.characters8(), view.length(), static_cast<uint8_t>(encoding));

result = Bun__encoding__constructFromLatin1(lexicalGlobalObject, span.data(), span.size(), static_cast<uint8_t>(encoding));
break;
}
case WebCore::BufferEncodingType::ascii: // ascii is a noop for latin1
case WebCore::BufferEncodingType::latin1: { // The native encoding is latin1, so we don't need to do any conversion.
result = JSValue::encode(createBuffer(lexicalGlobalObject, view.characters8(), view.length()));
result = JSValue::encode(createBuffer(lexicalGlobalObject, span.data(), span.size()));
break;
}
default: {
Expand All @@ -394,21 +399,22 @@ static JSC::EncodedJSValue constructFromEncoding(JSGlobalObject* lexicalGlobalOb
}
}
} else {
const auto span = view.span16();
switch (encoding) {
case WebCore::BufferEncodingType::utf8:
case WebCore::BufferEncodingType::base64:
case WebCore::BufferEncodingType::base64url:
case WebCore::BufferEncodingType::hex:
case WebCore::BufferEncodingType::ascii:
case WebCore::BufferEncodingType::latin1: {
result = Bun__encoding__constructFromUTF16(lexicalGlobalObject, view.characters16(), view.length(), static_cast<uint8_t>(encoding));
result = Bun__encoding__constructFromUTF16(lexicalGlobalObject, span.data(), span.size(), static_cast<uint8_t>(encoding));
break;
}
case WebCore::BufferEncodingType::ucs2:
case WebCore::BufferEncodingType::utf16le: {
// The native encoding is UTF-16
// so we don't need to do any conversion.
result = JSValue::encode(createBuffer(lexicalGlobalObject, reinterpret_cast<const unsigned char*>(view.characters16()), view.length() * 2));
result = JSValue::encode(createBuffer(lexicalGlobalObject, reinterpret_cast<const unsigned char*>(span.data()), span.size() * 2));
break;
}
default: {
Expand Down Expand Up @@ -600,17 +606,19 @@ static inline JSC::EncodedJSValue jsBufferByteLengthFromStringAndEncoding(JSC::J
auto view = str->tryGetValue(lexicalGlobalObject);

if (view.is8Bit()) {
if (view.characters8()[length - 1] == 0x3D) {
const auto span = view.span8();
if (span.data()[length - 1] == 0x3D) {
length--;

if (length > 1 && view.characters8()[length - 1] == '=')
if (length > 1 && span.data()[length - 1] == '=')
length--;
}
} else {
if (view.characters16()[length - 1] == 0x3D) {
const auto span = view.span16();
if (span.data()[length - 1] == 0x3D) {
length--;

if (length > 1 && view.characters16()[length - 1] == '=')
if (length > 1 && span.data()[length - 1] == '=')
length--;
}
}
Expand All @@ -626,9 +634,11 @@ static inline JSC::EncodedJSValue jsBufferByteLengthFromStringAndEncoding(JSC::J
case WebCore::BufferEncodingType::utf8: {
auto view = str->tryGetValue(lexicalGlobalObject);
if (view.is8Bit()) {
written = Bun__encoding__byteLengthLatin1(view.characters8(), view.length(), static_cast<uint8_t>(encoding));
const auto span = view.span8();
written = Bun__encoding__byteLengthLatin1(span.data(), span.size(), static_cast<uint8_t>(encoding));
} else {
written = Bun__encoding__byteLengthUTF16(view.characters16(), view.length(), static_cast<uint8_t>(encoding));
const auto span = view.span16();
written = Bun__encoding__byteLengthUTF16(span.data(), span.size(), static_cast<uint8_t>(encoding));
}
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/bindings/NodeHTTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static EncodedJSValue assignHeadersFromUWebSockets(uWS::HttpRequest* request, JS
nameString = WTF::httpHeaderNameStringImpl(name);
lowercasedNameString = nameString;
} else {
nameString = String({ nameView.characters8(), nameView.length() });
nameString = nameView.toString();
lowercasedNameString = nameString.convertToASCIILowercase();
}

Expand Down
7 changes: 5 additions & 2 deletions src/bun.js/bindings/NodeURL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ JSC_DEFINE_HOST_FUNCTION(jsDomainToASCII, (JSC::JSGlobalObject * globalObject, J
UChar hostnameBuffer[hostnameBufferLength];
UErrorCode error = U_ZERO_ERROR;
UIDNAInfo processingDetails = UIDNA_INFO_INITIALIZER;
int32_t numCharactersConverted = uidna_nameToASCII(encoder, StringView(domain).characters16(), domain.length(), hostnameBuffer, hostnameBufferLength, &processingDetails, &error);
const auto span = domain.span16();
int32_t numCharactersConverted = uidna_nameToASCII(encoder, span.data(), span.size(), hostnameBuffer, hostnameBufferLength, &processingDetails, &error);

if (U_SUCCESS(error) && !(processingDetails.errors & ~allowedNameToASCIIErrors) && numCharactersConverted) {
return JSC::JSValue::encode(JSC::jsString(vm, WTF::String(std::span { hostnameBuffer, static_cast<unsigned int>(numCharactersConverted) })));
Expand Down Expand Up @@ -131,7 +132,9 @@ JSC_DEFINE_HOST_FUNCTION(jsDomainToUnicode, (JSC::JSGlobalObject * globalObject,
UErrorCode error = U_ZERO_ERROR;
UIDNAInfo processingDetails = UIDNA_INFO_INITIALIZER;

int32_t numCharactersConverted = uidna_nameToUnicode(encoder, StringView(domain).characters16(), domain.length(), hostnameBuffer, hostnameBufferLength, &processingDetails, &error);
const auto span = domain.span16();

int32_t numCharactersConverted = uidna_nameToUnicode(encoder, span.data(), span.size(), hostnameBuffer, hostnameBufferLength, &processingDetails, &error);

if (U_SUCCESS(error) && !(processingDetails.errors & ~allowedNameToUnicodeErrors) && numCharactersConverted) {
return JSC::JSValue::encode(JSC::jsString(vm, WTF::String(std::span { hostnameBuffer, static_cast<unsigned int>(numCharactersConverted) })));
Expand Down
4 changes: 2 additions & 2 deletions src/bun.js/bindings/PathInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ALWAYS_INLINE bool isAbsolutePath(WTF::String input)
auto len = input.length();
if (len < 1)
return false;
auto bytes = input.characters8();
const auto bytes = input.span8().data();
if (bytes[0] == '/' || bytes[0] == '\\')
return true;
if (len < 2)
Expand All @@ -32,7 +32,7 @@ ALWAYS_INLINE bool isAbsolutePath(WTF::String input)
auto len = input.length();
if (len < 1)
return false;
auto bytes = input.characters16();
const auto bytes = input.span16().data();
if (bytes[0] == '/' || bytes[0] == '\\')
return true;
if (len < 2)
Expand Down
4 changes: 2 additions & 2 deletions src/bun.js/bindings/ZigGlobalObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1493,15 +1493,15 @@ JSC_DEFINE_HOST_FUNCTION(functionBTOA,
LChar* ptr;
unsigned length = encodedString.length();
auto dest = WTF::String::createUninitialized(length, ptr);
WTF::StringImpl::copyCharacters(ptr, { encodedString.characters16(), length });
WTF::StringImpl::copyCharacters(ptr, encodedString.span16());
encodedString = WTFMove(dest);
}

unsigned length = encodedString.length();
RELEASE_AND_RETURN(
throwScope,
Bun__encoding__toString(
encodedString.characters8(),
encodedString.span8().data(),
length,
globalObject,
static_cast<uint8_t>(WebCore::BufferEncodingType::base64)));
Expand Down
Loading

0 comments on commit e58d67b

Please sign in to comment.