Skip to content

Commit 4b7c17a

Browse files
Merge pull request #546 from lightpanda-io/jsruntime_js_to_null_terminated_string
Support binding JS strings to [:0]const u8
2 parents 1849f4c + 9f7446b commit 4b7c17a

File tree

3 files changed

+35
-35
lines changed

3 files changed

+35
-35
lines changed

src/browser/dom/implementation.zig

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,20 @@ pub const DOMImplementation = struct {
3131

3232
pub fn _createDocumentType(
3333
_: *DOMImplementation,
34-
qname: []const u8,
35-
publicId: []const u8,
36-
systemId: []const u8,
37-
state: *SessionState,
34+
qname: [:0]const u8,
35+
publicId: [:0]const u8,
36+
systemId: [:0]const u8,
3837
) !*parser.DocumentType {
39-
const allocator = state.arena;
40-
const cqname = try allocator.dupeZ(u8, qname);
41-
defer allocator.free(cqname);
42-
43-
const cpublicId = try allocator.dupeZ(u8, publicId);
44-
defer allocator.free(cpublicId);
45-
46-
const csystemId = try allocator.dupeZ(u8, systemId);
47-
defer allocator.free(csystemId);
48-
49-
return try parser.domImplementationCreateDocumentType(cqname, cpublicId, csystemId);
38+
return try parser.domImplementationCreateDocumentType(qname, publicId, systemId);
5039
}
5140

5241
pub fn _createDocument(
5342
_: *DOMImplementation,
54-
namespace: ?[]const u8,
55-
qname: ?[]const u8,
43+
namespace: ?[:0]const u8,
44+
qname: ?[:0]const u8,
5645
doctype: ?*parser.DocumentType,
57-
state: *SessionState,
5846
) !*parser.Document {
59-
const allocator = state.arena;
60-
var cnamespace: ?[:0]const u8 = null;
61-
if (namespace) |ns| {
62-
cnamespace = try allocator.dupeZ(u8, ns);
63-
}
64-
defer if (cnamespace) |v| allocator.free(v);
65-
66-
var cqname: ?[:0]const u8 = null;
67-
if (qname) |qn| {
68-
cqname = try allocator.dupeZ(u8, qn);
69-
}
70-
defer if (cqname) |v| allocator.free(v);
71-
72-
return try parser.domImplementationCreateDocument(cnamespace, cqname, doctype);
47+
return try parser.domImplementationCreateDocument(namespace, qname, doctype);
7348
}
7449

7550
pub fn _createHTMLDocument(_: *DOMImplementation, title: ?[]const u8) !*parser.DocumentHTML {
@@ -79,8 +54,6 @@ pub const DOMImplementation = struct {
7954
pub fn _hasFeature(_: *DOMImplementation) bool {
8055
return true;
8156
}
82-
83-
pub fn deinit(_: *DOMImplementation, _: std.mem.Allocator) void {}
8457
};
8558

8659
// Tests

src/runtime/js.zig

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1925,7 +1925,13 @@ fn Caller(comptime E: type) type {
19251925
},
19261926
.slice => {
19271927
if (ptr.child == u8) {
1928-
return valueToString(self.call_allocator, js_value, self.isolate, self.context);
1928+
if (ptr.sentinel()) |s| {
1929+
if (comptime s == 0) {
1930+
return valueToStringZ(self.call_allocator, js_value, self.isolate, self.context);
1931+
}
1932+
} else {
1933+
return valueToString(self.call_allocator, js_value, self.isolate, self.context);
1934+
}
19291935
}
19301936

19311937
// TODO: TypedArray
@@ -2319,6 +2325,15 @@ fn valueToString(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, con
23192325
return buf;
23202326
}
23212327

2328+
fn valueToStringZ(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, context: v8.Context) ![:0]u8 {
2329+
const str = try value.toString(context);
2330+
const len = str.lenUtf8(isolate);
2331+
const buf = try allocator.allocSentinel(u8, len, 0);
2332+
const n = str.writeUtf8(isolate, buf);
2333+
std.debug.assert(n == len);
2334+
return buf;
2335+
}
2336+
23222337
const NoopInspector = struct {
23232338
pub fn onInspectorResponse(_: *anyopaque, _: u32, _: []const u8) void {}
23242339
pub fn onInspectorEvent(_: *anyopaque, _: []const u8) void {}

src/runtime/test_primitive_types.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ const Primitives = struct {
9696
pub fn _checkOptionalReturnString(_: *const Primitives) ?[]const u8 {
9797
return "ok";
9898
}
99+
100+
pub fn _echoString(_: *const Primitives, a: []const u8) []const u8 {
101+
return a;
102+
}
103+
104+
pub fn _echoStringZ(_: *const Primitives, a: [:0]const u8) []const u8 {
105+
return a;
106+
}
99107
};
100108

101109
const testing = @import("testing.zig");
@@ -172,5 +180,9 @@ test "JS: primitive types" {
172180
.{ "p.checkOptionalReturn() === true;", "true" },
173181
.{ "p.checkOptionalReturnNull() === null;", "true" },
174182
.{ "p.checkOptionalReturnString() === 'ok';", "true" },
183+
184+
// strings
185+
.{ "p.echoString('over 9000!');", "over 9000!" },
186+
.{ "p.echoStringZ('Teg');", "Teg" },
175187
}, .{});
176188
}

0 commit comments

Comments
 (0)