This commit is contained in:
Jarred Sumner
2021-09-08 16:57:10 -07:00
parent d18e73aa57
commit c30ec608b1
12 changed files with 47 additions and 453 deletions

View File

@@ -2042,406 +2042,6 @@ pub const StringView = extern struct {
};
};
pub const Cpp = struct {
pub const Function = fn (
globalObject: *JSGlobalObject,
callframe: CallFrame,
) callconv(.C) JSValue;
pub const Getter = fn (
ctx: ?*c_void,
globalObject: *JSGlobalObject,
this: EncodedJSValue,
propertyName: PropertyName,
) callconv(.C) JSValue;
pub const Setter = fn (
ctx: ?*c_void,
globalObject: *JSGlobalObject,
this: JSValue,
value: JSValue,
propertyName: PropertyName,
) callconv(.C) bool;
pub const Tag = enum {
Callback,
Constructor,
Attribute,
Static,
};
pub const Attribute = struct {
getter: ?StaticExport = null,
setter: ?StaticExport = null,
read_only: bool = false,
enumerable: bool = false,
};
pub const Static = union {
String: []const u8,
Number: u16,
};
pub const Callback = StaticExport;
pub const LUTType = enum {
Function,
Accessor,
CellProperty,
ClassStructure,
PropertyCallback,
};
pub const LUTFlag = enum {
Enum,
DontEnum,
ReadOnly,
};
pub const Property = struct {
name: []const u8,
read_only: bool = false,
enumerable: bool = false,
value: Value,
pub const Value = union(Tag) {
Callback: StaticExport,
Constructor: StaticExport,
Attribute: Attribute,
Static: Static,
};
};
pub const Subclass = enum {
JSNonFinalObject,
JSObject,
};
pub const InitCallback = fn (*c_void, *VM, *JSGlobalObject) void;
pub const ClassDefinition = struct {
name: []const u8,
subclass: Subclass,
statics: []Property,
init: StaticExport,
free: StaticExport,
Ctx: type,
pub fn printer(h: std.fs.File.Writer, cpp: std.fs.File.Writer, comptime Type: type, comptime ZigType: type, comptime Prototype_: ?type, comptime Properties: []Property, comptime use_lut: bool) !void {
var instanceName = comptime Type.name;
instanceName[0] = comptime std.ascii.toLower(instanceName[0]);
const fields = comptime .{
.TypeName = Type.name,
.instanceName = instanceName,
};
try h.print(
\\#pragma once
\\
\\#include "root.h"
\\#include "headers.h"
\\
\\namespace Zig {{
\\
\\ class {[TypeName][s]} : public JSC::JSNonFinalObject {{
\\ using Base = JSC::JSNonFinalObject;
\\ static {s}* create(JSC::Structure* structure, JSC::JSGlobalThis* globalObject)
\\ {{
\\ {[TypeName][s]}* ptr = new (NotNull, JSC::allocateCell<{s}>(globalObject->vm().heap)) {[TypeName][s]}(structure, *globalObject);
\\ ptr->finishCreation(globalObject->vm());
\\ return ptr;
\\ }}
\\
\\ static {s}* create(JSC::Structure* structure, JSC::JSGlobalThis* globalObject, void* zigBase)
\\ {{
\\ {[TypeName][s]}* ptr = new (NotNull, JSC::allocateCell<{s}>(globalObject->vm().heap)) {[TypeName][s]}(structure, *globalObject);
\\ ptr->finishCreation(globalObject->vm(), zigBase);
\\ return ptr;
\\ }}
,
fields,
);
try cpp.print(
\\#pragma once
\\
\\#include "root.h"
\\#include "headers.h"
\\#include {[TypeName][s]}.h
\\
, fields);
inline for (Properties) |property| {
switch (comptime property.value) {
.Callback => |Callback| {
try cpp.print("static JSC_DECLARE_HOST_FUNCTION({s});\n", .{Callback.wrappedName()});
},
.Constructor => |Constructor| {
try cpp.print("static JSC_DECLARE_HOST_FUNCTION({s});\n", .{Callback.wrappedName()});
},
.Attribute => |Attribute| {
try cpp.print(" ");
if (Attribute.getter) |getter| {
try cpp.print("static JSC_DECLARE_CUSTOM_GETTER({s});\n", .{Callback.wrappedName()});
}
if (comptime Attribute.setter) |setter| {
try cpp.print("static JSC_DECLARE_CUSTOM_SETTER({s});\n", .{Callback.wrappedName()});
}
try cpp.writeAll(" ");
},
.Static => |Static| {},
}
}
if (comptime use_lut) {
try cpp.print(
\\namespace Zig {
\\ #include {[TypeName][s]}.lut.h
\\}
\\
\\ /* Source for {[TypeName][s]}.lut.h */
\\ @begin {[instanceName][s]}Table
,
fields,
);
inline for (Properties) |property| {
try cpp.writeAll(" ");
try cpp.writeAll(comptime property.name);
try cpp.writeAll(" ");
switch (comptime property.value) {
.Callback => |Callback| {
try cpp.writeAll(" ");
try cpp.writeAll(comptime Callback.wrappedName());
try cpp.writeAll(" ");
},
.Constructor => |Constructor| {
try cpp.writeAll(" ");
try cpp.writeAll(comptime Constructor.wrappedName());
try cpp.writeAll(" ");
},
.Attribute => |Attribute| {
try cpp.writeAll(" ");
if (Attribute.getter) |getter| {
try cpp.writeAll(comptime getter.wrappedName());
try cpp.writeAll(" ");
}
if (comptime Attribute.setter) |setter| {
@compileError("Unsupported setter on " ++ Type.name);
}
try cpp.writeAll(" ");
},
.Static => |Static| {},
}
var needs_or = false;
if (!property.enumerable) {
try cpp.writeAll("DontEnum");
needs_or = true;
}
if (needs_or) {
try cpp.writeAll("|");
}
switch (comptime property.value) {
.Callback => |Callback| {
const Fn: std.builtin.TypeInfo.Fn = comptime @typeInfo(Callback.Type).Fn;
try cpp.writeAll("Function {d}", .{Fn.args.len});
},
.Constructor => |Constructor| {
const Fn: std.builtin.TypeInfo.Fn = comptime @typeInfo(Callback.Type).Fn;
try cpp.writeAll("Function {d}", .{Fn.args.len});
},
.Attribute => |Attribute| {
try cpp.writeAll(" ");
if (Attribute.getter) |_| {
try cpp.writeAll("Accessor");
try cpp.writeAll(" ");
}
if (comptime Attribute.setter) |_| {
@compileError("Unsupported setter on " ++ Type.name);
}
try cpp.writeAll(" ");
},
.Static => |Static| {},
}
try cpp.writeAll("\n");
}
try cpp.writeAll(" @end\n");
try cpp.print(
\\namespace Zig {{
\\
\\ const ClassInfo {s}::s_info = {{ "{[TypeName][s]}", &Base::s_info, &{[instanceName][s]}Table, nullptr, CREATE_METHOD_TABLE({[TypeName][s]}) }};
\\
\\}}
\\
,
fields,
);
} else {
try cpp.print(
\\namespace Zig {{
\\
\\ const ClassInfo {[TypeName][s]}::s_info = {{ "{[TypeName][s]}", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE({[TypeName][s]}) }};
\\
\\}}
\\
, fields);
}
cpp.print(
\\
\\namespace Zig {{
\\
\\
\\
\\ class {[TypeName][s]} final : public JSC::JSNonFinalObject {{
\\ using Base = JSC::JSNonFinalObject;
\\
\\ void {[TypeName][s]}::finishCreation(JSGlobalObject* globalObject, VM& vm) {{
\\ Base::finishCreation(vm);
\\ m_zigBase = {[InitFunctionSymbol]}(globalObject, vm);
\\ reifyStaticProperties(vm, {[TypeName][s]}::info(), &{[instanceName][s]}Table, *this);
\\ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
\\ }}
\\
\\ void {[TypeName][s]}::finishCreation(JSGlobalObject* globalObject, VM& vm, void* zigBase) {{
\\ Base::finishCreation(vm);
\\ m_zigBase = zigBase;
\\ reifyStaticProperties(vm, {[TypeName][s]}::info(), &{[instanceName][s]}Table, *this);
\\ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
\\ }}
\\
\\
,
fields,
);
inline for (Properties) |property| {
switch (comptime property.value) {
.Callback => |Callback| {
try cpp.writeAll(
\\JSC_DEFINE_HOST_FUNCTION({[Wrapped][s]}, (JSGlobalObject* globalObject, CallFrame* callFrame))
\\{{
\\ VM& vm = globalObject->vm();
\\ auto scope = DECLARE_THROW_SCOPE(vm);
\\ auto* thisValue = JSC::jsDynamic<{[TypeName][s]}*>(callFrame->thisValue());
\\ if (UNLIKELY(!thisValue || !thisValue.m_zigBase)) {{
\\ return JSC::throwVMTypeError(globalObject, scope);
\\ }}
\\
\\ RELEASE_AND_RETURN(scope, {[Fn][s]}(thisValue.m__zigType, vm, this, globalObject, callFrame, scope));
\\}}
\\
, .{
.Wrapped = Callback.wrappedName(),
.Fn = Callback.symbol_name,
.TypeName = Type.name,
});
},
.Constructor => |Constructor| {
try cpp.writeAll(
\\JSC_DEFINE_HOST_FUNCTION({[Wrapped][s]}, (JSGlobalObject* globalObject, CallFrame* callFrame))
\\{{
\\ VM& vm = globalObject->vm();
\\ auto scope = DECLARE_THROW_SCOPE(vm);
\\ RELEASE_AND_RETURN(scope, {[Fn][s]}(globalObject, vm, callFrame, scope));
\\}}
\\
, .{
.Wrapped = Constructor.wrappedName(),
.Fn = Constructor.symbol_name,
.TypeName = Type.name,
});
},
.Attribute => |Attribute| {
try cpp.writeAll(" ");
if (Attribute.getter) |getter| {
try cpp.print(
\\JSC_DEFINE_CUSTOM_GETTER({s}, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)
\\{{
\\ auto& vm = JSC::getVM(&lexicalGlobalObject);
\\ auto throwScope = DECLARE_THROW_SCOPE(vm);
\\}}
, .{Callback.wrappedName()});
}
if (comptime Attribute.setter) |setter| {
try cpp.print(
\\JSC_DEFINE_CUSTOM_SETTER({s}, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)
\\{{
\\
\\}}
, .{Callback.wrappedName()});
}
try cpp.writeAll(" ");
},
.Static => |Static| {},
}
}
if (Prototype_) |Prototype| {
h.print(
\\
\\
\\
\\
,
fields,
);
} else {}
h.print(
\\ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) {{
\\ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
\\ }}
\\
\\ EXPORT_DECLARE_INFO;
\\
\\ template<typename, JSC::SubspaceAccess mode> static JSC::IsoSubspace* subspaceFor(JSC::VM& vm)
\\ {{
\\ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
\\ return nullptr;
\\ return &vm.plainObjectSpace;
\\ }}
\\ private:
\\ {[TypeName][s]}(JSC::VM& vm, JSC::Structure* structure) : Base(vm, structure) {{
\\ m_zigBase = nullptr;
\\ }}
\\ void finishCreation(VM&);
\\ void* m_zigBase;
\\
\\}}
\\
\\
\\
,
fields,
);
}
// pub fn generateShimType(comptime Parent: type, comptime _name: []const u8, comptime static_properties: anytype) type {
// const Base = struct {
// const BaseType = @This();
// bytes: shim.Bytes,
// const cppFn = shim.cppFn;
// pub const include = "Zig__" ++ _name;
// pub const name = "Zig::" ++ _name;
// pub const namespace = "Zig";
// pub const shim = comptime Shimmer(namespace, name, BaseType);
// pub fn create(global: *JSGlobalObject, parent: *Parent) JSValue {}
// pub fn getZigType(this: *BaseType, global: *JSGlobalObject) JSValue {}
// pub fn finalize(this: *BaseType, global: *JSGlobalObject) JSValue {}
// };
// }
};
};
pub usingnamespace @import("exports.zig");
pub const Callback = struct {