aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-03 20:49:48 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-03 20:52:17 -0700
commitaa0be51d40afe4d49d6474db9e270564511f2171 (patch)
tree4717cea98b3e3faf6cb9c2ad36dc3b0ad2b5364b /src
parent77bab6c7823899f82d7c3ea9d39b29432e24fb8e (diff)
downloadbun-aa0be51d40afe4d49d6474db9e270564511f2171.tar.gz
bun-aa0be51d40afe4d49d6474db9e270564511f2171.tar.zst
bun-aa0be51d40afe4d49d6474db9e270564511f2171.zip
Fix test failures from `JSPropertyIterator` change
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/api/ffi.zig6
-rw-r--r--src/bun.js/api/transpiler.zig26
-rw-r--r--src/bun.js/bindings/bindings.zig196
-rw-r--r--src/bun.js/bindings/exports.zig14
-rw-r--r--src/js_ast.zig6
5 files changed, 92 insertions, 156 deletions
diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig
index afe442096..59d682d3b 100644
--- a/src/bun.js/api/ffi.zig
+++ b/src/bun.js/api/ffi.zig
@@ -561,7 +561,7 @@ pub const FFI = struct {
var symbols_iter = JSC.JSPropertyIterator(.{
.skip_empty_name = true,
- .name_encoding = .utf8,
+
.include_value = true,
}).init(global.ref(), object.asObjectRef());
defer symbols_iter.deinit();
@@ -572,14 +572,14 @@ pub const FFI = struct {
const value = symbols_iter.value;
if (value.isEmptyOrUndefinedOrNull()) {
- return JSC.toTypeError(JSC.Node.ErrorCode.ERR_INVALID_ARG_VALUE, "Expected an object for key \"{s}\"", .{prop}, global.ref());
+ return JSC.toTypeError(JSC.Node.ErrorCode.ERR_INVALID_ARG_VALUE, "Expected an object for key \"{any}\"", .{prop}, global.ref());
}
var function: Function = .{};
if (try generateSymbolForFunction(global, allocator, value, &function)) |val| {
return val;
}
- function.base_name = try allocator.dupeZ(u8, prop);
+ function.base_name = try prop.toOwnedSliceZ(allocator);
symbols.putAssumeCapacity(std.mem.span(function.base_name.?), function);
}
diff --git a/src/bun.js/api/transpiler.zig b/src/bun.js/api/transpiler.zig
index a21f40e2e..8d6d2c141 100644
--- a/src/bun.js/api/transpiler.zig
+++ b/src/bun.js/api/transpiler.zig
@@ -364,8 +364,8 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
}
var define_iter = JSC.JSPropertyIterator(.{
- .skip_empty_name = false,
- .name_encoding = .utf8,
+ .skip_empty_name = true,
+
.include_value = true,
}).init(globalThis.ref(), define.asObjectRef());
defer define_iter.deinit();
@@ -385,7 +385,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
return transpiler;
}
- names[define_iter.i] = allocator.dupe(u8, prop) catch unreachable;
+ names[define_iter.i] = prop.toOwnedSlice(allocator) catch unreachable;
var val = JSC.ZigString.init("");
property_value.toZigString(&val, globalThis);
if (val.len == 0) {
@@ -500,6 +500,10 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
}
transpiler.runtime.allow_runtime = false;
+ transpiler.runtime.dynamic_require = switch (transpiler.transform.platform orelse .browser) {
+ .bun, .bun_macro => true,
+ else => false,
+ };
if (object.getIfPropertyExists(globalThis, "macro")) |macros| {
macros: {
@@ -639,28 +643,32 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var iter = JSC.JSPropertyIterator(.{
.skip_empty_name = true,
- .name_encoding = .utf8,
.include_value = true,
- .override_writing_cstring = true,
- }).initCStringBuffer(globalThis.ref(), replace.asObjectRef(), bun.default_allocator);
+ }).init(globalThis, replace.asObjectRef());
if (iter.len > 0) {
- errdefer iter.deinit(bun.default_allocator);
+ errdefer iter.deinit();
try replacements.ensureUnusedCapacity(bun.default_allocator, iter.len);
// We cannot set the exception before `try` because it could be
// a double free with the `errdefer`.
defer if (exception.* != null) {
- iter.deinit(bun.default_allocator);
+ iter.deinit();
+ for (replacements.keys()) |key| {
+ bun.default_allocator.free(bun.constStrToU8(key));
+ }
replacements.clearAndFree(bun.default_allocator);
};
- while (iter.next()) |key| {
+ while (iter.next()) |key_| {
const value = iter.value;
if (value.isEmpty()) continue;
+ var key = try key_.toOwnedSlice(bun.default_allocator);
+
if (!JSLexer.isIdentifier(key)) {
JSC.throwInvalidArguments("\"{s}\" is not a valid ECMAScript identifier", .{key}, ctx, exception);
+ bun.default_allocator.free(key);
return transpiler;
}
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index e4ccb379d..9f7771081 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -101,6 +101,33 @@ pub const ZigString = extern struct {
return this;
}
+ pub fn toOwnedSlice(this: ZigString, allocator: std.mem.Allocator) ![]u8 {
+ return try std.fmt.allocPrint(allocator, "{any}", .{this});
+ }
+
+ pub fn toOwnedSliceZ(this: ZigString, allocator: std.mem.Allocator) ![:0]u8 {
+ return try std.fmt.allocPrintZ(allocator, "{any}", .{this});
+ }
+
+ pub fn trunc(this: ZigString, len: usize) ZigString {
+ return .{ .ptr = this.ptr, .len = @minimum(len, this.len) };
+ }
+
+ pub fn eqlComptime(this: ZigString, comptime other: []const u8) bool {
+ if (this.len != other.len)
+ return false;
+
+ if (this.is16Bit()) {
+ return strings.eqlComptimeUTF16(this.utf16SliceAligned(), other);
+ }
+
+ if (comptime strings.isAllASCIISimple(other)) {
+ return strings.eqlComptimeIgnoreLen(this.slice(), other);
+ }
+
+ @compileError("Not implemented yet for latin1");
+ }
+
pub const shim = Shimmer("", "ZigString", @This());
pub const Slice = struct {
@@ -1455,6 +1482,19 @@ pub const SourceCode = extern struct {
pub const Thenables = opaque {};
+pub const StrongValue = opaque {
+ pub const shim = Shimmer("JSC", "JSFunction", @This());
+
+ const cppFn = shim.cppFn;
+ pub const include = "JavaScriptCore/JSFunction.h";
+ pub const name = "JSC::JSFunction";
+ pub const namespace = "JSC";
+
+ pub fn get(this: *StrongValue) JSValue {
+ return cppFn("get", .{this});
+ }
+};
+
pub const JSFunction = extern struct {
pub const shim = Shimmer("JSC", "JSFunction", @This());
bytes: shim.Bytes,
@@ -3667,30 +3707,16 @@ pub fn Thenable(comptime Then: type, comptime onResolve: fn (*Then, globalThis:
pub const JSPropertyIteratorOptions = struct {
skip_empty_name: bool,
- name_encoding: NameEncoding,
include_value: bool,
- /// Overrides the setup for the iterator's item to instead be a `usize`
- /// indicating the length of the latest property value and writes the
- override_writing_cstring: bool = false,
-
- pub const NameEncoding = enum {
- utf8,
- utf16,
- /// Constructs the strings with a variable encoding using JSC's string
- /// encoding API.
- infer,
- };
};
pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
- comptime if (options.override_writing_cstring) {
- if (options.name_encoding != .utf8) {
- @compileError(std.fmt.comptimePrint("{} is not a supported encoding when 'options.override_writing_cstring' is enabled. Try using utf8 instead.", .{options.name_encoding}));
- }
- };
-
return struct {
+ /// Position in the property list array
+ /// Update is deferred until the next iteration
i: u32 = 0,
+
+ iter_i: u32 = 0,
len: u32,
array_ref: JSC.C.JSPropertyNameArrayRef,
@@ -3704,29 +3730,16 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
/// Zero-sized when `options.include_value` is not enabled.
global: if (options.include_value) JSC.C.JSContextRef else void,
- /// The buffer for writing to when `options.override_writing_cstring`
- /// is enabled. Zero-sized when `options.override_writing_cstring` is
- /// not enabled.
- cstring_buffer: if (options.override_writing_cstring) []u8 else void,
- cstring_buffer_offset: if (options.override_writing_cstring) usize else void,
-
const Self = @This();
- pub const Item = switch (options.name_encoding) {
- .utf8 => []const u8,
- .utf16 => []const u16,
- .infer => ZigString,
- };
-
inline fn initInternal(global: JSC.C.JSContextRef, object: JSC.C.JSObjectRef) Self {
+ const array_ref = JSC.C.JSObjectCopyPropertyNames(global, object);
return .{
- .array_ref = JSC.C.JSObjectCopyPropertyNames(global, object),
- .len = @intCast(u32, JSC.C.JSPropertyNameArrayGetCount(object)),
+ .array_ref = array_ref,
+ .len = @truncate(u32, JSC.C.JSPropertyNameArrayGetCount(array_ref)),
.object = if (comptime options.include_value) object else .{},
.global = if (comptime options.include_value) global else .{},
.value = undefined,
- .cstring_buffer = undefined,
- .cstring_buffer_offset = undefined,
};
}
@@ -3739,75 +3752,23 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
return Self.initInternal(global, object);
}
- usingnamespace if (options.override_writing_cstring) struct {
- /// Initializes the iterator using the CString buffer created using your
- /// provided allocator. Note that this is requires two iterations for
- /// each item at the slowest speed because we need to do a look-ahead
- /// to preallocate the string buffer so it should only be used in
- /// secular cases.
- pub fn initCStringBuffer(global: JSC.C.JSContextRef, object: JSC.C.JSObjectRef, allocator: std.mem.Allocator) Self {
- var self = Self.initInternal(global, object);
- const total_len = self.peekTotalPropertyLengths();
- self.cstring_buffer = allocator.alloc(u8, total_len + self.len) catch unreachable;
- self.cstring_buffer_offset = 0;
- return self;
- }
-
- /// Deinitializes the property name array and all of the string
- /// references constructed by the copy along with the CString
- /// buffer. The allocator the CString buffer was initialized with
- /// **must** be the same as the one passed in here.
- pub inline fn deinit(self: *Self, allocator: std.mem.Allocator) void {
- JSC.C.JSPropertyNameArrayRelease(self.array_ref);
- allocator.free(self.cstring_buffer);
- }
-
- /// Deinitializes the property name array from JSC and returns the
- /// CString buffer. The caller owns the returned buffer and free the
- /// buffer with the same allocator as it was initialized with.
- pub inline fn toOwnedCStringBuffer(self: Self) []u8 {
- JSC.C.JSPropertyNameArrayRelease(self.array_ref);
- return self.cstring_buffer;
- }
- } else struct {
- /// Deinitializes the property name array and all of the string
- /// references constructed by the copy.
- pub inline fn deinit(self: *Self) void {
- JSC.C.JSPropertyNameArrayRelease(self.array_ref);
- }
- };
+ /// Deinitializes the property name array and all of the string
+ /// references constructed by the copy.
+ pub inline fn deinit(self: *Self) void {
+ JSC.C.JSPropertyNameArrayRelease(self.array_ref);
+ }
/// Finds the next property string and, if `options.include_value` is
/// enabled, updates the `iter.value` to respect the latest property's
/// value. Also note the behavior of the other options.
- pub fn next(self: *Self) ?Item {
- if (self.i == self.len) return null;
-
- var property_name_ref = JSC.C.JSPropertyNameArrayGetNameAtIndex(self.array_ref, self.i);
- self.i += 1;
-
- if (comptime options.override_writing_cstring) {
- const start = self.cstring_buffer_offset;
-
- // The JSStringGetUTF8CString returns a null terminated string
- // and writes to the buffer. We just need to adjust the length
- // to update the slice to hold the items wrote to the pointer
- // because we already those bytes are allocated from the initial
- // iteration.
- self.cstring_buffer_offset += JSC.C.JSStringGetUTF8CString(property_name_ref, self.cstring_buffer.ptr + start, self.cstring_buffer.len - start);
-
- const prop = self.cstring_buffer[start..self.cstring_buffer_offset];
-
- if (comptime options.skip_empty_name) {
- if (prop.len == 0) return self.next();
- }
-
- if (comptime options.include_value) {
- self.value = JSC.JSValue.fromRef(JSC.C.JSObjectGetProperty(self.global, self.object, property_name_ref, null));
- }
-
- return prop;
+ pub fn next(self: *Self) ?ZigString {
+ if (self.iter_i >= self.len) {
+ self.i = self.iter_i;
+ return null;
}
+ self.i = self.iter_i;
+ var property_name_ref = JSC.C.JSPropertyNameArrayGetNameAtIndex(self.array_ref, self.iter_i);
+ self.iter_i += 1;
const len = JSC.C.JSStringGetLength(property_name_ref);
@@ -3815,25 +3776,11 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
if (len == 0) return self.next();
}
- const prop = switch (comptime options.name_encoding) {
- .utf8 => JSC.C.JSStringGetCharacters8Ptr(property_name_ref)[0..len],
- .utf16 => JSC.C.JSStringGetCharactersPtr(property_name_ref)[0..len],
- .infer => blk: {
- const enc = JSC.C.JSStringEncoding(property_name_ref);
- break :blk switch (enc) {
- .empty => ZigString.Empty,
- .char8 => blk2: {
- var s = ZigString.init((JSC.C.JSStringGetCharacters8Ptr(property_name_ref))[0..len]);
- s.markUTF8();
- break :blk2 s;
- },
- .char16 => blk2: {
- var s = ZigString.init16(JSC.C.JSStringGetCharactersPtr(property_name_ref)[0..len]);
- s.markUTF16();
- break :blk2 s;
- },
- };
- },
+ const prop = switch (JSC.C.JSStringEncoding(property_name_ref)) {
+ .empty => ZigString.Empty,
+ // latin1
+ .char8 => ZigString.init((JSC.C.JSStringGetCharacters8Ptr(property_name_ref))[0..len]),
+ .char16 => ZigString.init16(JSC.C.JSStringGetCharactersPtr(property_name_ref)[0..len]),
};
if (comptime options.include_value) {
@@ -3842,20 +3789,5 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
return prop;
}
-
- /// Finds the combined lengths of all of the unconsumed string property
- /// names without advancing the iterator. Starts from the current index
- /// in the iterator.
- pub fn peekTotalPropertyLengths(self: *const Self) usize {
- var i = self.i;
- var total: usize = 0;
-
- while (i < self.len) : (i += 1) {
- const ref = JSC.C.JSPropertyNameArrayGetNameAtIndex(self.array_ref, i);
- total += JSC.C.JSStringGetLength(ref);
- }
-
- return total;
- }
};
}
diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig
index 14c6412f3..159bc4d0e 100644
--- a/src/bun.js/bindings/exports.zig
+++ b/src/bun.js/bindings/exports.zig
@@ -1930,7 +1930,7 @@ pub const ZigConsoleClient = struct {
var props_iter = JSC.JSPropertyIterator(.{
.skip_empty_name = true,
- .name_encoding = .utf8,
+
.include_value = true,
}).init(this.globalThis.ref(), props.asObjectRef());
defer props_iter.deinit();
@@ -1938,13 +1938,12 @@ pub const ZigConsoleClient = struct {
var children_prop = props.get(this.globalThis, "children");
if (props_iter.len > 0) {
{
- var i: usize = 0;
this.indent += 1;
defer this.indent -|= 1;
const count_without_children = props_iter.len - @as(usize, @boolToInt(children_prop != null));
while (props_iter.next()) |prop| {
- if (strings.eqlComptime(prop, "children"))
+ if (prop.eqlComptime("children"))
continue;
var property_value = props_iter.value;
@@ -1957,7 +1956,7 @@ pub const ZigConsoleClient = struct {
writer.print(
comptime Output.prettyFmt("<r><blue>{s}<d>=<r>", enable_ansi_colors),
- .{prop[0..@minimum(prop.len, 128)]},
+ .{prop.trunc(128)},
);
if (tag.cell.isStringLike()) {
@@ -1977,17 +1976,17 @@ pub const ZigConsoleClient = struct {
if (
// count_without_children is necessary to prevent printing an extra newline
// if there are children and one prop and the child prop is the last prop
- i + 1 < count_without_children and
+ props_iter.i + 1 < count_without_children and
// 3 is arbitrary but basically
// <input type="text" value="foo" />
// ^ should be one line
// <input type="text" value="foo" bar="true" baz={false} />
// ^ should be multiple lines
- i > 3)
+ props_iter.i > 3)
{
writer.writeAll("\n");
this.writeIndent(Writer, writer_) catch unreachable;
- } else if (i + 1 < count_without_children) {
+ } else if (props_iter.i + 1 < count_without_children) {
writer.writeAll(" ");
}
}
@@ -2090,7 +2089,6 @@ pub const ZigConsoleClient = struct {
{
var props_iter = JSC.JSPropertyIterator(.{
.skip_empty_name = true,
- .name_encoding = .infer,
.include_value = true,
}).init(this.globalThis.ref(), object);
defer props_iter.deinit();
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 3c6b6de44..eb28091c9 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -6993,7 +6993,6 @@ pub const Macro = struct {
var array_iter = JSC.JSPropertyIterator(.{
.skip_empty_name = true,
- .name_encoding = .utf8,
.include_value = true,
}).init(writer.ctx, import_namespace_arg.asObjectRef());
defer array_iter.deinit();
@@ -7018,7 +7017,7 @@ pub const Macro = struct {
if (!JSLexer.isIdentifier(alias)) throwTypeError(writer.ctx, "import alias must be an identifier", writer.exception);
import.import.items[import_item_i] = ClauseItem{
- .alias = name,
+ .alias = name.toOwnedSlice(writer.allocator) catch return false,
.original_name = alias,
.name = .{ .loc = writer.loc, .ref = Ref.None },
.alias_loc = writer.loc,
@@ -7934,7 +7933,6 @@ pub const Macro = struct {
var object = value.asObjectRef();
var object_iter = JSC.JSPropertyIterator(.{
.skip_empty_name = false,
- .name_encoding = .utf8,
.include_value = true,
}).init(this.global.ref(), object);
defer object_iter.deinit();
@@ -7952,7 +7950,7 @@ pub const Macro = struct {
while (object_iter.next()) |prop| {
properties[object_iter.i] = G.Property{
- .key = Expr.init(E.String, E.String.init(this.allocator.dupe(u8, prop) catch unreachable), this.caller.loc),
+ .key = Expr.init(E.String, E.String.init(prop.toOwnedSlice(this.allocator) catch unreachable), this.caller.loc),
.value = try this.run(object_iter.value),
};
}