mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-30 15:41:48 +00:00
Poor support for functions/namespaces.
If you look at the specification for `console` [1], you'll note that it's a
namespace, not an interface (like most things). Furthermore, MDN lists its
methods as "static".
But it's a pretty weird namespace IMO, because some of its "functions", like
`count` can have state associated with them.
This causes some problems with our current implementation. Something like:
```
[1].forEach(console.log)
```
Fails, since `this` isn't our window-attached Console instance.
This commit introducing a new `static_XYZ` naming convention which does not
have the class/Self as a receiver:
```
pub fn static_log(values: []JsObject, page: *Page) !void {
```
This turns Console into a namespace for these specific functions, while still
being used normally for those functions that require state.
We could infer this behavior from the first parameter, but that seems more
error prone. For now, I prefer having the explicit `static_` prefix.
[1] https://console.spec.whatwg.org/#console-namespace
This commit is contained in:
@@ -1680,6 +1680,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
||||
}
|
||||
} else if (comptime std.mem.startsWith(u8, name, "get_")) {
|
||||
generateProperty(Struct, name[4..], isolate, template_proto);
|
||||
} else if (comptime std.mem.startsWith(u8, name, "static_")) {
|
||||
generateFunction(Struct, name[7..], isolate, template_proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1769,6 +1771,23 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
||||
template_proto.set(js_name, function_template, v8.PropertyAttribute.None);
|
||||
}
|
||||
|
||||
fn generateFunction(comptime Struct: type, comptime name: []const u8, isolate: v8.Isolate, template_proto: v8.ObjectTemplate) void {
|
||||
const js_name = v8.String.initUtf8(isolate, name).toName();
|
||||
const function_template = v8.FunctionTemplate.initCallback(isolate, struct {
|
||||
fn callback(raw_info: ?*const v8.C_FunctionCallbackInfo) callconv(.c) void {
|
||||
const info = v8.FunctionCallbackInfo.initFromV8(raw_info);
|
||||
var caller = Caller(Self, State).init(info);
|
||||
defer caller.deinit();
|
||||
|
||||
const named_function = comptime NamedFunction.init(Struct, "static_" ++ name);
|
||||
caller.function(Struct, named_function, info) catch |err| {
|
||||
caller.handleError(Struct, named_function, err, info);
|
||||
};
|
||||
}
|
||||
}.callback);
|
||||
template_proto.set(js_name, function_template, v8.PropertyAttribute.None);
|
||||
}
|
||||
|
||||
fn generateAttribute(comptime Struct: type, comptime name: []const u8, isolate: v8.Isolate, template: v8.FunctionTemplate, template_proto: v8.ObjectTemplate) void {
|
||||
const zig_value = @field(Struct, name);
|
||||
const js_value = simpleZigValueToJs(isolate, zig_value, true);
|
||||
@@ -2154,6 +2173,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
||||
return @ptrFromInt(@intFromPtr(toa.ptr) + @as(usize, @intCast(offset)));
|
||||
}
|
||||
if (prototype_index == type_index) {
|
||||
// When a type has itself as the prototype, then we've
|
||||
// reached the end of the chain.
|
||||
return error.InvalidArgument;
|
||||
}
|
||||
type_index = prototype_index;
|
||||
@@ -2341,6 +2362,14 @@ fn Caller(comptime E: type, comptime State: type) type {
|
||||
info.getReturnValue().set(try scope.zigValueToJs(res));
|
||||
}
|
||||
|
||||
fn function(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void {
|
||||
const scope = self.scope;
|
||||
const func = @field(Struct, named_function.name);
|
||||
const args = try self.getArgs(Struct, named_function, 0, info);
|
||||
const res = @call(.auto, func, args);
|
||||
info.getReturnValue().set(try scope.zigValueToJs(res));
|
||||
}
|
||||
|
||||
fn getter(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void {
|
||||
const scope = self.scope;
|
||||
const func = @field(Struct, named_function.name);
|
||||
|
||||
Reference in New Issue
Block a user