Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix the rest of node:buffer #15722

Draft
wants to merge 50 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2a1a431
fix test-buffer-zero-fill-cli.js
nektro Dec 11, 2024
2699eda
fix test-buffer-alloc.js
nektro Dec 11, 2024
5d00fcd
fix test-buffer-bytelength.js
nektro Dec 11, 2024
975a339
fix test-buffer-compare.js
nektro Dec 11, 2024
b2077dd
fix test-buffer-concat.js
nektro Dec 11, 2024
fde51e7
fix test-buffer-constants.js
nektro Dec 11, 2024
0168fa8
fix test-buffer-copy.js
nektro Dec 11, 2024
158c581
fix test-buffer-equals.js
nektro Dec 11, 2024
7535c58
fix test-buffer-fill.js
nektro Dec 11, 2024
814ac87
fix test-buffer-writeuint.js
nektro Dec 11, 2024
ba777b8
fix test-buffer-writeint.js
nektro Dec 11, 2024
bdb9772
fix test-buffer-writefloat.js
nektro Dec 11, 2024
8a9b9f5
fix test-buffer-writedouble.js
nektro Dec 11, 2024
28a7c40
fix test-buffer-write.js
nektro Dec 11, 2024
eef6fc8
fix test-buffer-readuint.js
nektro Dec 11, 2024
89795bf
fix test-buffer-readint.js
nektro Dec 11, 2024
237e4df
fix test-buffer-readfloat.js
nektro Dec 11, 2024
5b650bc
fix test-buffer-readdouble.js
nektro Dec 11, 2024
f108c3c
fix test-buffer-read.js
nektro Dec 12, 2024
ba86ff1
fix test-buffer-new.js
nektro Dec 12, 2024
db74f9c
fix test-buffer-bigint64.js
nektro Dec 12, 2024
af0fd9d
fix test-buffer-backing-arraybuffer.js
nektro Dec 12, 2024
3f810a3
fix test-buffer-arraybuffer.js
nektro Dec 12, 2024
72e5b7e
fixed correctness issue in ERR_INVALID_ARG_TYPE
nektro Dec 12, 2024
8fd46d4
fix regression
nektro Dec 12, 2024
3b3c29e
add scripts/check-node-all.sh
nektro Dec 12, 2024
d13a47f
fix regressions
nektro Dec 12, 2024
d56586e
fix test-buffer-badhex.js
nektro Dec 12, 2024
d45c4d8
fix test-buffer-from.js
nektro Dec 12, 2024
d0eb4a6
fix test-buffer-sharedarraybuffer.js
nektro Dec 12, 2024
58b7515
move main impl of Buffer.from back to JSBufferConstructor
nektro Dec 13, 2024
3778be8
misc fixes
nektro Dec 13, 2024
7a911c1
Merge remote-tracking branch 'origin/main' into nektro-patch-52129
nektro Dec 13, 2024
9dff935
Merge remote-tracking branch 'origin/main' into nektro-patch-52129
nektro Dec 13, 2024
18b2969
fix test-stream-unshift-empty-chunk.js regression
nektro Dec 13, 2024
1cf31b8
webkit upgrade for test-buffer-alloc.js
nektro Dec 13, 2024
e49cc4d
fix test-buffer-indexof.js
nektro Dec 13, 2024
15c4304
fix test-buffer-includes.js
nektro Dec 13, 2024
eeb2803
fix includes on linux, memmem on macos isn't posix compliant
nektro Dec 14, 2024
b692263
fix windows build
nektro Dec 14, 2024
4a332e6
fix linux x64
nektro Dec 14, 2024
befcab8
cleaner name
nektro Dec 14, 2024
48eff0f
share implementation
nektro Dec 14, 2024
37d3472
these commented tests are fixed
nektro Dec 14, 2024
4d49408
only read getters once
nektro Dec 14, 2024
fc3a95d
dont create JSString for ASCIILiteral
nektro Dec 14, 2024
9201b88
address comments
nektro Dec 14, 2024
8b17029
dont create JSString for ASCIILiteral
nektro Dec 14, 2024
ab1e149
Merge branch 'main' into nektro-patch-52129
Jarred-Sumner Dec 15, 2024
c052ebf
Merge branch 'main' into nektro-patch-52129
nektro Dec 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/tools/SetupWebKit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")

if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION 58549ddc4d9e7164823fe9d4e86c46c003e46a19)
set(WEBKIT_VERSION 801394a84b529e1186e92103307e3c09adcc86e5)
endif()

if(WEBKIT_LOCAL)
Expand Down
18 changes: 18 additions & 0 deletions scripts/check-node-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

i=0
j=0

for x in $(find test/js/node/test/parallel -type f -name "test-$1*.js")
do
i=$((i+1))
echo ./$x
if timeout 2 $PWD/build/debug/bun-debug ./$x
then
j=$((j+1))
fi
echo
done

echo $i tests tested
echo $j tests passed
3 changes: 1 addition & 2 deletions src/bun.js/ConsoleObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ pub const FormatOptions = struct {
if (try arg1.getBooleanLoose(globalThis, "sorted")) |opt| {
formatOptions.ordered_properties = opt;
}

if (try arg1.getBooleanLoose(globalThis, "compact")) |opt| {
formatOptions.single_line = opt;
}
Expand Down Expand Up @@ -2148,7 +2147,7 @@ pub const Formatter = struct {
this.addForNewLine(description.len + "()".len);
writer.print(comptime Output.prettyFmt("<r><blue>Symbol({any})<r>", enable_ansi_colors), .{description});
} else {
writer.print(comptime Output.prettyFmt("<r><blue>Symbol<r>", enable_ansi_colors), .{});
writer.print(comptime Output.prettyFmt("<r><blue>Symbol()<r>", enable_ansi_colors), .{});
}
},
.Error => {
Expand Down
13 changes: 13 additions & 0 deletions src/bun.js/api/BunObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,19 @@ pub fn inspect(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.J
return ret;
}

export fn Bun__inspect(globalThis: *JSGlobalObject, value: JSValue) ZigString {
// very stable memory address
var array = MutableString.init(getAllocator(globalThis), 0) catch unreachable;
var buffered_writer = MutableString.BufferedWriter{ .context = &array };
const writer = buffered_writer.writer();

var formatter = ConsoleObject.Formatter{ .globalThis = globalThis };
writer.print("{}", .{value.toFmt(&formatter)}) catch return ZigString.Empty;
buffered_writer.flush() catch return ZigString.Empty;

return ZigString.init(array.slice()).withEncoding();
}

pub fn getInspect(globalObject: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue {
const fun = JSC.createCallback(globalObject, ZigString.static("inspect"), 2, inspect);
var str = ZigString.init("nodejs.util.inspect.custom");
Expand Down
144 changes: 128 additions & 16 deletions src/bun.js/bindings/ErrorCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ JSObject* createError(Zig::JSGlobalObject* globalObject, ErrorCode code, JSC::JS
return createError(vm, globalObject, code, message);
}

// export fn Bun__inspect(globalThis: *JSGlobalObject, value: JSValue) ZigString
extern "C" ZigString Bun__inspect(JSC::JSGlobalObject* globalObject, JSValue value);

WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
{
ASSERT(!arg.isEmpty());
Expand All @@ -201,14 +204,14 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
auto name = JSC::getCalculatedDisplayName(vm, cell->getObject());
if (catchScope.exception()) {
catchScope.clearException();
name = "Function"_s;
name = ""_s;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = ""_s;
return "[Function: (anonymous)]"_s;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assuming that is fine to ignore this exception

}

if (!name.isNull() && name.length() > 0) {
return makeString("[Function: "_s, name, ']');
}

return "Function"_s;
return "[Function: (anonymous)]"_s;
break;
}

Expand All @@ -217,34 +220,133 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
}
}

return arg.toWTFStringForConsole(globalObject);
// return arg.toWTFString(globalObject); // this threw an exception on `{ __proto__: null }`
ZigString zstring = Bun__inspect(globalObject, arg);
BunString bstring(BunStringTag::ZigString, BunStringImpl(zstring));
return bstring.toWTFString();
}

WTF::String determineSpecificType(JSC::JSGlobalObject* globalObject, JSValue value)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);

if (value.isNull()) {
return String("null"_s);
}
if (value.isUndefined()) {
return String("undefined"_s);
}
if (value.isBigInt()) {
auto str = value.toStringOrNull(globalObject);
if (!str) return {};
return makeString("type bigint ("_s, str->getString(globalObject), "n)"_s);
}
if (value.isNumber()) {
double d = value.asNumber();
double infinity = std::numeric_limits<double>::infinity();
if (value == 0) return (1 / d == -infinity) ? String("type number (-0)"_s) : String("type number (0)"_s);
if (d != d) return String("type number (NaN)"_s);
if (d == infinity) return String("type number (Infinity)"_s);
if (d == -infinity) return String("type number (-Infinity)"_s);
auto str = value.toStringOrNull(globalObject);
if (!str) return {};
return makeString("type number ("_s, str->getString(globalObject), ")"_s);
}
if (value.isBoolean()) {
return value.asBoolean() ? String("type boolean (true)"_s) : String("type boolean (false)"_s);
}
if (value.isSymbol()) {
auto cell = value.asCell();
auto symbol = jsCast<Symbol*>(cell);
auto result = symbol->tryGetDescriptiveString();
auto description = result.has_value() ? result.value() : String("Symbol()"_s);
return makeString("type symbol ("_s, description, ")"_s);
}
if (value.isCallable()) {
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto cell = value.asCell();
auto name = JSC::getCalculatedDisplayName(vm, cell->getObject());
if (scope.exception()) {
scope.clearException();
name = String(""_s);
}
if (!name.isNull() && name.length() > 0) {
return makeString("function "_s, name);
}
return String("function"_s);
}
if (value.isObject()) {
auto constructor = value.get(globalObject, vm.propertyNames->constructor);
RETURN_IF_EXCEPTION(scope, {});
if (constructor.toBoolean(globalObject)) {
auto name = constructor.get(globalObject, vm.propertyNames->name);
RETURN_IF_EXCEPTION(scope, {});
auto str = name.toString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
return makeString("an instance of "_s, str->getString(globalObject));
}
// return `${lazyInternalUtilInspect().inspect(value, { depth: -1 })}`;
auto str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return str;
}
if (value.isString()) {
auto str = value.toString(globalObject)->getString(globalObject);
if (str.length() > 28) {
str = str.substring(0, 25);
str = makeString(str, "..."_s);
if (!str.contains('\'')) {
return makeString("type string ('"_s, str, "')"_s);
}
}
// return `type string (${JSONStringify(value)})`;
str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return makeString("type string ("_s, str, ")"_s);
}

// value = lazyInternalUtilInspect().inspect(value, { colors: false });
auto str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return str;
}

namespace Message {

WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, const StringView& expected_type, JSValue actual_value)
{
auto actual_value_string = JSValueToStringSafe(globalObject, actual_value);
auto actual_value_string = determineSpecificType(globalObject, actual_value);
RETURN_IF_EXCEPTION(scope, {});

return makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received: "_s, actual_value_string);
return makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received "_s, actual_value_string);
}

WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, ArgList expected_types, JSValue actual_value)
{
WTF::StringBuilder result;

auto actual_value_string = JSValueToStringSafe(globalObject, actual_value);
auto actual_value_string = determineSpecificType(globalObject, actual_value);
RETURN_IF_EXCEPTION(scope, {});

result.append("The \""_s, arg_name, "\" argument must be of type "_s);
result.append("The "_s);

if (arg_name.contains(' ')) {
result.append(arg_name);
} else {
result.append("\""_s);
result.append(arg_name);
result.append("\" argument"_s);
}
result.append(" must be of type "_s);

unsigned length = expected_types.size();
if (length == 1) {
result.append(expected_types.at(0).toWTFString(globalObject));
} else if (length == 2) {
result.append(expected_types.at(0).toWTFString(globalObject));
result.append(" or "_s);
result.append(", or "_s);
result.append(expected_types.at(1).toWTFString(globalObject));
} else {
for (unsigned i = 0; i < length - 1; i++) {
Expand All @@ -253,11 +355,11 @@ WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* gl
JSValue expected_type = expected_types.at(i);
result.append(expected_type.toWTFString(globalObject));
}
result.append(" or "_s);
result.append(", or "_s);
result.append(expected_types.at(length - 1).toWTFString(globalObject));
}

result.append(". Received: "_s, actual_value_string);
result.append(". Received "_s, actual_value_string);

return result.toString();
}
Expand Down Expand Up @@ -295,27 +397,33 @@ WTF::String ERR_OUT_OF_RANGE(JSC::ThrowScope& scope, JSC::JSGlobalObject* global
auto input = JSValueToStringSafe(globalObject, val_input);
RETURN_IF_EXCEPTION(scope, {});

return makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received: "_s, input);
return makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received "_s, input);
}

}

namespace ERR {

JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral arg_name, WTF::ASCIILiteral expected_type, JSC::JSValue val_actual_value)
JSC::EncodedJSValue throwCode(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ErrorCode code, const WTF::String& message)
{
throwScope.throwException(globalObject, createError(globalObject, code, message));
return {};
}

JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value)
{
auto arg_kind = String(arg_name).startsWith("options."_s) ? "property"_s : "argument"_s;
auto ty_first_char = expected_type[0];
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;

auto actual_value = JSValueToStringSafe(globalObject, val_actual_value);
auto actual_value = determineSpecificType(globalObject, val_actual_value);
RETURN_IF_EXCEPTION(throwScope, {});

auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message));
return {};
}
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue val_arg_name, WTF::ASCIILiteral expected_type, JSC::JSValue val_actual_value)
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue val_arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value)
{
auto arg_name = val_arg_name.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, {});
Expand All @@ -324,7 +432,7 @@ JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalO
auto ty_first_char = expected_type[0];
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;

auto actual_value = JSValueToStringSafe(globalObject, val_actual_value);
auto actual_value = determineSpecificType(globalObject, val_actual_value);
RETURN_IF_EXCEPTION(throwScope, {});

auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
Expand Down Expand Up @@ -442,8 +550,12 @@ JSC::EncodedJSValue STRING_TOO_LONG(JSC::ThrowScope& throwScope, JSC::JSGlobalOb
return {};
}

JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject)
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& name)
{
if (!name.isEmpty()) {
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, makeString("\""_s, name, "\" is outside of buffer bounds"_s)));
return {};
}
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, "Attempt to access memory outside buffer bounds"_s));
return {};
}
Expand Down
8 changes: 5 additions & 3 deletions src/bun.js/bindings/ErrorCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ enum Bound {

namespace ERR {

JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral arg_name, WTF::ASCIILiteral expected_type, JSC::JSValue val_actual_value);
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name, WTF::ASCIILiteral expected_type, JSC::JSValue val_actual_value);
JSC::EncodedJSValue throwCode(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ErrorCode code, const WTF::String& message);

JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value);
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue val_arg_name, const WTF::String& val_expected_type, JSC::JSValue val_actual_value);
JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, size_t lower, size_t upper, JSC::JSValue actual);
JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name, size_t lower, size_t upper, JSC::JSValue actual);
JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name_val, size_t bound_num, Bound bound, JSC::JSValue actual);
Expand All @@ -87,7 +89,7 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal
JSC::EncodedJSValue UNKNOWN_ENCODING(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& encoding);
JSC::EncodedJSValue INVALID_STATE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& statemsg);
JSC::EncodedJSValue STRING_TOO_LONG(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& name);
JSC::EncodedJSValue UNKNOWN_SIGNAL(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue signal, bool triedUppercase = false);
JSC::EncodedJSValue SOCKET_BAD_PORT(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue name, JSC::JSValue port, bool allowZero);

Expand Down
Loading
Loading