diff options
26 files changed, 1625 insertions, 431 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index 3142f4812..590185982 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -90,8 +90,7 @@ "--resolve=lazy", "--outdir=public", "--serve", - "--public-url=http://localhost:9000/", - "--framework=./framework.tsx" + "--public-url=http://localhost:9000/" ], "cwd": "${workspaceFolder}/demos/css-stress-test", "console": "internalConsole" @@ -38,7 +38,8 @@ CLANG_FLAGS = -Isrc/JavaScript/jsc/WebKit/WebKitBuild/Release/JavaScriptCore/Pri -Isrc/javascript/jsc/WebKit/Source/bmalloc \ -std=gnu++17 \ -stdlib=libc++ \ - -DDU_DISABLE_RENAMING=1 + -DDU_DISABLE_RENAMING=1 \ + -Wall jsc-bindings-mac: $(OBJ_FILES) @@ -118,7 +118,9 @@ pub fn build(b: *std.build.Builder) void { var javascript = b.addExecutable("spjs", "src/main_javascript.zig"); var typings_exe = b.addExecutable("typescript-decls", "src/javascript/jsc/typescript.zig"); - + javascript.setMainPkgPath(b.pathFromRoot(".")); + typings_exe.setMainPkgPath(b.pathFromRoot(".")); + exe.setMainPkgPath(b.pathFromRoot(".")); // exe.want_lto = true; if (!target.getCpuArch().isWasm()) { b.default_step.dependOn(&exe.step); @@ -167,11 +169,12 @@ pub fn build(b: *std.build.Builder) void { const headers_step = b.step("headers", "JSC headers"); var headers_exec: *std.build.LibExeObjStep = b.addExecutable("headers", "src/javascript/jsc/bindings/bindings-generator.zig"); var headers_runner = headers_exec.run(); + headers_exec.setMainPkgPath(javascript.main_pkg_path.?); headers_step.dependOn(&headers_runner.step); b.default_step.dependOn(&exe.step); - var steps = [_]*std.build.LibExeObjStep{ exe, javascript, typings_exe }; + var steps = [_]*std.build.LibExeObjStep{ javascript, typings_exe }; for (steps) |step| { step.linkLibC(); diff --git a/demos/css-stress-test/src/components/button.tsx b/demos/css-stress-test/src/components/button.tsx index 3f55fae34..7d7b6623e 100644 --- a/demos/css-stress-test/src/components/button.tsx +++ b/demos/css-stress-test/src/components/button.tsx @@ -25,13 +25,3 @@ const Button = ({ label, label2, onClick }) => { </div> ); }; - -const Bacon = Button; - -export { Bacon, Bacon as Button }; - -const RefreshLike = () => {}; - -const useBacon = () => { - return [1, 8]; -}; diff --git a/demos/css-stress-test/src/index.tsx b/demos/css-stress-test/src/index.tsx index 9c317fc08..c9ec51a7e 100644 --- a/demos/css-stress-test/src/index.tsx +++ b/demos/css-stress-test/src/index.tsx @@ -1,5 +1,7 @@ import { Main } from "./main"; import classNames from "classnames"; +import * as ReactDOM from "react-dom"; + const Base = ({}) => { const name = typeof location !== "undefined" @@ -9,7 +11,6 @@ const Base = ({}) => { }; function startReact() { - const ReactDOM = require("react-dom"); ReactDOM.render(<Base />, document.querySelector("#reactroot")); } @@ -21,8 +22,9 @@ if (typeof window !== "undefined") { startReact(); } else { - const ReactDOMServer = require("react-dom/server.browser"); console.log(ReactDOMServer.renderToString(<Base />)); } export { Base }; + + diff --git a/src/bundler.zig b/src/bundler.zig index b74487a50..facf965f0 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -1721,7 +1721,7 @@ pub fn NewBundler(cache_files: bool) type { ) !options.TransformResult { var bundler = try ThisBundler.init(allocator, log, opts, null); bundler.configureLinker(); - try bundler.configureRouter(); + // try bundler.configureRouter(); var skip_normalize = false; if (bundler.router) |router| { diff --git a/src/http.zig b/src/http.zig index 0514e88aa..59fb6debf 100644 --- a/src/http.zig +++ b/src/http.zig @@ -1294,7 +1294,7 @@ pub const RequestContext = struct { ); // It will call flush for us automatically - defer ctx.bundler.resetStore(); + ctx.bundler.resetStore(); var written = ctx.bundler.buildWithResolveResult( resolve_result, ctx.allocator, @@ -1674,25 +1674,25 @@ pub const Server = struct { } if (req_ctx.url.extname.len == 0 and !RequestContext.JavaScriptHandler.javascript_disabled) { - if (server.bundler.options.framework != null) { - RequestContext.JavaScriptHandler.enqueue(&req_ctx, server) catch unreachable; - server.javascript_enabled = !RequestContext.JavaScriptHandler.javascript_disabled; - } + // if (server.bundler.options.framework != null) { + // RequestContext.JavaScriptHandler.enqueue(&req_ctx, server) catch unreachable; + // server.javascript_enabled = !RequestContext.JavaScriptHandler.javascript_disabled; + // } } - if (!req_ctx.controlled) { - req_ctx.handleRequest() catch |err| { - switch (err) { - error.ModuleNotFound => { - req_ctx.sendNotFound() catch {}; - }, - else => { - Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path }); - return; - }, - } - }; - } + // if (!req_ctx.controlled) { + req_ctx.handleRequest() catch |err| { + switch (err) { + error.ModuleNotFound => { + req_ctx.sendNotFound() catch {}; + }, + else => { + Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path }); + return; + }, + } + }; + // } if (!req_ctx.controlled) { const status = req_ctx.status orelse @intCast(HTTPStatusCode, 500); @@ -1725,7 +1725,7 @@ pub const Server = struct { }; server.bundler = try Bundler.init(allocator, &server.log, options, null); server.bundler.configureLinker(); - try server.bundler.configureRouter(); + // try server.bundler.configureRouter(); try server.initWatcher(); diff --git a/src/javascript/jsc/bindings/ZigConsoleClient.cpp b/src/javascript/jsc/bindings/ZigConsoleClient.cpp new file mode 100644 index 000000000..c8e3ec37d --- /dev/null +++ b/src/javascript/jsc/bindings/ZigConsoleClient.cpp @@ -0,0 +1,99 @@ +#include "helpers.h" + +#include "ZigConsoleClient.h" +#include <JavaScriptCore/ConsoleClient.h> +#include <JavaScriptCore/ConsoleMessage.h> +#include <JavaScriptCore/ScriptArguments.h> +#include <wtf/text/WTFString.h> + +using ScriptArguments = Inspector::ScriptArguments; +using MessageType = JSC::MessageType; +using MessageLevel = JSC::MessageLevel; +using JSGlobalObject = JSC__JSGlobalObject; + +using String = WTF::String; + +JSC__JSValue Inspector__ScriptArguments__argumentAt(const Inspector__ScriptArguments* arg0, size_t i) { +return JSC::JSValue::encode(arg0->argumentAt(i)); +} +size_t Inspector__ScriptArguments__argumentCount(const Inspector__ScriptArguments* arg0) { + return arg0->argumentCount(); +} +bWTF__String Inspector__ScriptArguments__getFirstArgumentAsString(const Inspector__ScriptArguments* arg0) { + WTF::String str; + arg0->getFirstArgumentAsString(str); + Wrap<WTF::String, bWTF__String> wrap = Wrap<WTF::String, bWTF__String>(str); + return wrap.result; +} + +bool Inspector__ScriptArguments__isEqual(const Inspector__ScriptArguments* arg0, const Inspector__ScriptArguments* arg1) { + return arg0->isEqual(*arg1); +} +void Inspector__ScriptArguments__release(Inspector__ScriptArguments* arg0) { + arg0->deref(); +} + +void Zig::ConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments) { + Zig__ConsoleClient__messageWithTypeAndLevel(static_cast<uint32_t>(type), static_cast<uint32_t>(level), globalObject, arguments.ptr()); +} +void Zig::ConsoleClient::count(JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__count(globalObject, ptr, label.length()); +} + +void Zig::ConsoleClient::countReset(JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__countReset(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::profile(JSC::JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__profile(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::profileEnd(JSC::JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__profileEnd(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::takeHeapSnapshot(JSC::JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__takeHeapSnapshot(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::time(JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__time(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::timeLog(JSGlobalObject* globalObject, const String& label, Ref<ScriptArguments>&& arguments) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__timeLog(globalObject, ptr, label.length(), arguments.ptr()); +} +void Zig::ConsoleClient::timeEnd(JSGlobalObject* globalObject, const String& label) +{ + const char* ptr = reinterpret_cast<const char*>(label.characters8()); + Zig__ConsoleClient__timeEnd(globalObject, ptr, label.length()); +} +void Zig::ConsoleClient::timeStamp(JSGlobalObject* globalObject, Ref<ScriptArguments>&& args) +{ + Zig__ConsoleClient__timeStamp(globalObject, args.ptr()); +} +void Zig::ConsoleClient::record(JSGlobalObject*, Ref<ScriptArguments>&&) +{ + +} +void Zig::ConsoleClient::recordEnd(JSGlobalObject*, Ref<ScriptArguments>&&) +{ + +} +void Zig::ConsoleClient::screenshot(JSGlobalObject*, Ref<ScriptArguments>&&) +{ + +} +void Zig::ConsoleClient::warnUnimplemented(const String& method) +{ + +}
\ No newline at end of file diff --git a/src/javascript/jsc/bindings/ZigConsoleClient.h b/src/javascript/jsc/bindings/ZigConsoleClient.h new file mode 100644 index 000000000..11b4c6758 --- /dev/null +++ b/src/javascript/jsc/bindings/ZigConsoleClient.h @@ -0,0 +1,59 @@ +#pragma once + +#include <JavaScriptCore/ConsoleClient.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace Inspector { +class InspectorConsoleAgent; +class InspectorDebuggerAgent; +class InspectorScriptProfilerAgent; +} +namespace Zig { + using InspectorConsoleAgent = Inspector::InspectorConsoleAgent; + using InspectorDebuggerAgent = Inspector::InspectorDebuggerAgent; + using InspectorScriptProfilerAgent = Inspector::InspectorScriptProfilerAgent; + + +class ConsoleClient final : public JSC::ConsoleClient { + WTF_MAKE_FAST_ALLOCATED; +public: + explicit ConsoleClient(InspectorConsoleAgent*); + ~ConsoleClient() final { } + + static bool logToSystemConsole(); + static void setLogToSystemConsole(bool); + + void setDebuggerAgent(InspectorDebuggerAgent* agent) { m_debuggerAgent = agent; } + void setPersistentScriptProfilerAgent(InspectorScriptProfilerAgent* agent) { m_scriptProfilerAgent = agent; } + +private: + void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) final; + void count(JSC::JSGlobalObject*, const String& label) final; + void countReset(JSC::JSGlobalObject*, const String& label) final; + void profile(JSC::JSGlobalObject*, const String& title) final; + void profileEnd(JSC::JSGlobalObject*, const String& title) final; + void takeHeapSnapshot(JSC::JSGlobalObject*, const String& title) final; + void time(JSC::JSGlobalObject*, const String& label) final; + void timeLog(JSC::JSGlobalObject*, const String& label, Ref<Inspector::ScriptArguments>&&) final; + void timeEnd(JSC::JSGlobalObject*, const String& label) final; + void timeStamp(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) final; + void record(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) final; + void recordEnd(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) final; + void screenshot(JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&) final; + + void warnUnimplemented(const String& method); + void internalAddMessage(MessageType, MessageLevel, JSC::JSGlobalObject*, Ref<Inspector::ScriptArguments>&&); + + void startConsoleProfile(); + void stopConsoleProfile(); + + Inspector::InspectorConsoleAgent* m_consoleAgent; + Inspector::InspectorDebuggerAgent* m_debuggerAgent { nullptr }; + Inspector::InspectorScriptProfilerAgent* m_scriptProfilerAgent { nullptr }; + Vector<String> m_profiles; + bool m_profileRestoreBreakpointActiveValue { false }; +}; + +} + diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp new file mode 100644 index 000000000..e17e3aeba --- /dev/null +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -0,0 +1,164 @@ + +#include "ZigGlobalObject.h" +#include "helpers.h" + +#include <JavaScriptCore/CallFrameInlines.h> +#include <JavaScriptCore/CatchScope.h> +#include <JavaScriptCore/Completion.h> +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/Exception.h> +#include <JavaScriptCore/JSContextInternal.h> +#include <JavaScriptCore/JSInternalPromise.h> +#include <JavaScriptCore/JSModuleLoader.h> +#include <JavaScriptCore/JSNativeStdFunction.h> +#include <JavaScriptCore/JSPromise.h> +#include <JavaScriptCore/JSSourceCode.h> +#include <JavaScriptCore/JSValueInternal.h> +#include <JavaScriptCore/JSVirtualMachineInternal.h> +#include <JavaScriptCore/ObjectConstructor.h> +#include <JavaScriptCore/SourceOrigin.h> +#include <JavaScriptCore/Identifier.h> +#include <wtf/URL.h> +#include <JavaScriptCore/ClassInfo.h> +#include <JavaScriptCore/JSString.h> +#include <JavaScriptCore/VM.h> +#include <JavaScriptCore/WasmFaultSignalHandler.h> +#include <JavaScriptCore/JSCast.h> +#include <JavaScriptCore/InitializeThreading.h> + +#include <JavaScriptCore/JSLock.h> + +using JSGlobalObject = JSC::JSGlobalObject; +using Exception = JSC::Exception; +using JSValue = JSC::JSValue; +using JSString = JSC::JSString; +using JSModuleLoader = JSC::JSModuleLoader; +using JSModuleRecord = JSC::JSModuleRecord; +using Identifier = JSC::Identifier; +using SourceOrigin = JSC::SourceOrigin; +namespace JSCastingHelpers = JSC::JSCastingHelpers; + + +JSC__JSGlobalObject* Zig__GlobalObject__create(JSC__VM* arg0) { + // There are assertions that the apiLock is set while the JSGlobalObject is initialized. + if (arg0 != nullptr) { + JSC::VM& vm = reinterpret_cast<JSC__VM&>(arg0); + vm.apiLock().lock(); + Zig::GlobalObject* globalObject = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::jsNull())); + vm.apiLock().unlock(); + return static_cast<JSC__JSGlobalObject*>(globalObject); + } + + JSC::initialize(); + + JSC::VM& vm = JSC::VM::create(JSC::LargeHeap, nullptr); + vm.apiLock().lock(); + + + #if ENABLE(WEBASSEMBLY) + JSC::Wasm::enableFastMemory(); + #endif + + Zig::GlobalObject* globalObject = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::jsNull())); + vm.apiLock().unlock(); + return static_cast<JSC__JSGlobalObject*>(globalObject); +} + +namespace Zig { + +const JSC::ClassInfo GlobalObject::s_info = { "GlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(GlobalObject) }; + +const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { + &supportsRichSourceInfo, + &shouldInterruptScript, + &javaScriptRuntimeFlags, + nullptr, // queueTaskToEventLoop +nullptr, // &shouldInterruptScriptBeforeTimeout, + &moduleLoaderImportModule, // moduleLoaderImportModule + &moduleLoaderResolve, // moduleLoaderResolve + &moduleLoaderFetch, // moduleLoaderFetch + &moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties + &moduleLoaderEvaluate, // moduleLoaderEvaluate + &promiseRejectionTracker, // promiseRejectionTracker + &reportUncaughtExceptionAtEventLoop, + ¤tScriptExecutionOwner, + &scriptExecutionStatus, + nullptr, // defaultLanguage + nullptr, // compileStreaming + nullptr, // instantiateStreaming +}; + +void GlobalObject::reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObject, Exception* exception) { + Zig__GlobalObject__reportUncaughtException(globalObject, exception); +} + +void GlobalObject::promiseRejectionTracker(JSGlobalObject* obj, JSC::JSPromise* prom, JSC::JSPromiseRejectionOperation reject) { + Zig__GlobalObject__promiseRejectionTracker(obj, prom, reject == JSC::JSPromiseRejectionOperation::Reject ? 0 : 1); +} + +JSC::Identifier GlobalObject::moduleLoaderResolve( + JSGlobalObject* globalObject, + JSModuleLoader* loader, + JSValue key, + JSValue referrer, + JSValue origin +) { + auto res = Zig__GlobalObject__resolve( + globalObject, + loader, + JSValue::encode(key), + JSValue::encode(referrer), + nullptr + ); + + Wrap<JSC::Identifier, bJSC__Identifier> wrapped = Wrap<JSC::Identifier, bJSC__Identifier>(res); + return *wrapped.cpp; +} + +JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader* loader, JSString* specifierValue, JSValue referrer, const SourceOrigin& sourceOrigin) { + return Zig__GlobalObject__import( + globalObject, + loader, + specifierValue, + JSC::JSValue::encode(referrer), + &sourceOrigin + ); +} + +JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, JSModuleLoader* loader, JSValue key, JSValue value1, JSValue value2) { + return Zig__GlobalObject__fetch( + globalObject, + loader, + JSValue::encode(key), + JSValue::encode(value1), + JSValue::encode(value2) + ); +} + +JSC::JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, JSModuleLoader* loader, JSValue key, JSModuleRecord* record, JSValue val) { + auto res = Zig__GlobalObject__createImportMetaProperties( + globalObject, + loader, + JSValue::encode(key), + record, + JSValue::encode(val) + ); + + return JSValue::decode(res).getObject(); +} + +JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode) { + auto res = Zig__GlobalObject__eval( + globalObject, + moduleLoader, + JSValue::encode(key), + JSValue::encode(moduleRecordValue), + JSValue::encode(scriptFetcher), + JSValue::encode(sentValue), + JSValue::encode(resumeMode) + ); + + return JSValue::decode(res); +} + +}
\ No newline at end of file diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.h b/src/javascript/jsc/bindings/ZigGlobalObject.h index 7436bc531..b7bf7e00b 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.h +++ b/src/javascript/jsc/bindings/ZigGlobalObject.h @@ -1,3 +1,5 @@ +#include "root.h" + #pragma once namespace JSC { @@ -7,56 +9,56 @@ namespace JSC { } - +#include <JavaScriptCore/Structure.h> #include <JavaScriptCore/JSGlobalObject.h> +#include <JavaScriptCore/JSTypeInfo.h> +namespace Zig { +class GlobalObject final : public JSC::JSGlobalObject { + using Base = JSC::JSGlobalObject; -namespace Zig { - using namespace JSC; - -class GlobalObject final : public JSGlobalObject { public: - using Base = JSGlobalObject; DECLARE_EXPORT_INFO; - static const GlobalObjectMethodTable s_globalObjectMethodTable; + static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable; static constexpr bool needsDestruction = true; - template<typename CellType, SubspaceAccess mode> - static IsoSubspace* subspaceFor(VM& vm) + template<typename CellType, JSC::SubspaceAccess mode> + static JSC::IsoSubspace* subspaceFor(JSC::VM& vm) { return vm.apiGlobalObjectSpace<mode>(); } - static GlobalObject* create(VM& vm, Structure* structure) + static GlobalObject* create(JSC::VM& vm, JSC::Structure* structure) { - auto* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure); + auto* object = new (NotNull, JSC::allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure); object->finishCreation(vm); return object; } - static Structure* createStructure(VM& vm, JSValue prototype) + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype) { - auto* result = Structure::create(vm, nullptr, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); + auto* result = JSC::Structure::create(vm, nullptr, prototype, JSC::TypeInfo(JSC::GlobalObjectType, Base::StructureFlags), info()); result->setTransitionWatchpointIsLikelyToBeFired(true); return result; } - static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, Exception*); - - static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSModuleLoader*, JSString* moduleNameValue, JSValue parameters, const SourceOrigin&); - static Identifier moduleLoaderResolve(JSGlobalObject*, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue); - static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue); - static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue); - static JSValue moduleLoaderEvaluate(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue, JSValue, JSValue); - + static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, JSC::Exception*); + static JSC::JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSString* moduleNameValue, JSC::JSValue parameters, const JSC::SourceOrigin&); + static JSC::Identifier moduleLoaderResolve(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue keyValue, JSC::JSValue referrerValue, JSC::JSValue); + static JSC::JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue); + static JSC::JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSModuleRecord*, JSC::JSValue); + static JSC::JSValue moduleLoaderEvaluate(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue); + static void promiseRejectionTracker(JSGlobalObject*, JSC::JSPromise*, JSC::JSPromiseRejectionOperation); private: - GlobalObject(VM& vm, Structure* structure) - : Base(vm, structure, &s_globalObjectMethodTable) - { } + + GlobalObject(JSC::VM& vm, JSC::Structure* structure) + : JSC::JSGlobalObject(vm, structure, &s_globalObjectMethodTable) + { + } }; } diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp index 7120285c1..45d22f59d 100644 --- a/src/javascript/jsc/bindings/bindings.cpp +++ b/src/javascript/jsc/bindings/bindings.cpp @@ -13,7 +13,6 @@ #include <wtf/text/StringView.h> #include <JavaScriptCore/Identifier.h> #include <JavaScriptCore/VM.h> -#include <JavaScriptCore/VM.h> #include <JavaScriptCore/WasmFaultSignalHandler.h> #include <wtf/text/StringCommon.h> #include <JavaScriptCore/FunctionConstructor.h> @@ -25,70 +24,7 @@ #include <JavaScriptCore/JSMap.h> #include <JavaScriptCore/JSSet.h> -template<class CppType, typename ZigType> -class Wrap { -public: - Wrap(){ - }; - - Wrap(ZigType zig){ - result = zig; - cpp = static_cast<CppType*>(static_cast<void*>(&zig)); - }; - - Wrap(CppType _cpp){ - char* buffer = alignedBuffer(); - memcpy(buffer, std::move(reinterpret_cast<char*>(reinterpret_cast<void*>(&_cpp))), sizeof(CppType)); - cpp = reinterpret_cast<CppType*>(buffer); - }; - - - ~Wrap(){}; - - char* alignedBuffer() { - return result.bytes + alignof(CppType) - reinterpret_cast<intptr_t>(result.bytes) % alignof(CppType); - } - - ZigType result; - CppType* cpp; - - static ZigType wrap(CppType obj) { - return *static_cast<ZigType*>(static_cast<void*>(&obj)); - } - - static ZigType wrap(CppType* obj) { - return *static_cast<ZigType*>(static_cast<void*>(obj)); - } -}; - - - - - -template<class To, class From> -To cast(From v) -{ - return *static_cast<To*>(static_cast<void*>(v)); -} - -template<class To, class From> -To ccast(From v) -{ - return *static_cast<const To*>(static_cast<const void*>(v)); -} - -typedef JSC__JSValue (* NativeCallbackFunction)(void* arg0, JSC__JSGlobalObject* arg1, JSC__CallFrame* arg2); - -static const JSC::ArgList makeArgs(JSC__JSValue* v, size_t count) { - JSC::MarkedArgumentBuffer args = JSC::MarkedArgumentBuffer(); - args.ensureCapacity(count); - for (size_t i = 0; i < count; ++i) { - args.append(JSC::JSValue::decode(v[i])); - } - - return JSC::ArgList(args); -} - +#include "helpers.h" extern "C" { @@ -131,8 +67,7 @@ JSC__JSObject* JSC__JSString__toObject(JSC__JSString* arg0, JSC__JSGlobalObject* return arg0->toObject(arg1); } bWTF__String JSC__JSString__value(JSC__JSString* arg0, JSC__JSGlobalObject* arg1) { - auto wrap = Wrap<WTF__String, bWTF__String>::wrap(arg0->value(arg1)); - return wrap.result; + return Wrap<WTF__String, bWTF__String>::wrap(arg0->value(arg1)); } #pragma mark - JSC::JSModuleLoader @@ -452,7 +387,10 @@ JSC__JSString* JSC__JSValue__toStringOrNull(JSC__JSValue JSValue0, JSC__JSGlobal JSC::JSValue value = JSC::JSValue::decode(JSValue0); return value.toStringOrNull(arg1); } - +bWTF__String JSC__JSValue__toWTFString(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1) { + JSC::JSValue value = JSC::JSValue::decode(JSValue0); + return Wrap<WTF::String, bWTF__String>(value.toWTFString(arg1)); +}; #pragma mark - JSC::PropertyName diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index c9c0b100d..c7b69a23d 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -1,193 +1,10 @@ -usingnamespace @import("./imports.zig"); +usingnamespace @import("../../../global.zig"); const std = @import("std"); -const main = @import("root"); -const is_bindgen = std.meta.trait.hasDecls(main, .{"bindgen"}); +const is_bindgen: bool = std.meta.globalOption("bindgen", bool) orelse false; const hasRef = std.meta.trait.hasField("ref"); const StaticExport = @import("./static_export.zig"); -const Sizes = @import("./sizes.zig"); - -pub fn Shimmer(comptime _namespace: []const u8, comptime _name: []const u8, comptime Parent: type) type { - return struct { - pub const namespace = _namespace; - pub const name = _name; - - fn toCppType(comptime FromType: ?type) ?type { - return comptime brk: { - var NewReturnType = FromType orelse c_void; - - if (NewReturnType == c_void) { - break :brk FromType; - } - - var ReturnTypeInfo: std.builtin.TypeInfo = @typeInfo(FromType orelse c_void); - - if (ReturnTypeInfo == .Pointer and NewReturnType != *c_void) { - NewReturnType = ReturnTypeInfo.Pointer.child; - ReturnTypeInfo = @typeInfo(NewReturnType); - } - - switch (ReturnTypeInfo) { - .Union, - .Struct, - .Enum, - => { - if (@hasDecl(ReturnTypeInfo, "Type")) { - break :brk NewReturnType; - } - }, - else => {}, - } - - break :brk FromType; - }; - } - pub const align_of_symbol = std.fmt.comptimePrint("{s}__{s}_object_align_", .{ namespace, name }); - pub const size_of_symbol = std.fmt.comptimePrint("{s}__{s}_object_size_", .{ namespace, name }); - pub const byte_size = brk: { - const identifier = std.fmt.comptimePrint("{s}__{s}", .{ namespace, name }); - const align_symbol = std.fmt.comptimePrint("{s}__{s}_align", .{ namespace, name }); - if (@hasDecl(Sizes, identifier)) { - break :brk @field(Sizes, identifier); //+ @field(Sizes, align_symbol); - } else { - break :brk 0; - } - }; - pub const Bytes = [byte_size]u8; - - pub inline fn getConvertibleType(comptime ZigType: type) type { - if (@typeInfo(ZigType) == .Struct) { - const Struct: std.builtin.TypeInfo.Struct = ChildType.Struct; - for (Struct.fields) |field| { - if (std.mem.eql(u8, field.name, "ref")) { - return field.field_type; - } - } - } - - return ZigType; - } - - fn pointerChild(comptime Type: type) type { - if (@typeInfo(Type) == .Pointer) { - return @typeInfo(Type).Pointer.child_type; - } - - return Type; - } - - pub inline fn toZigType(comptime ZigType: type, comptime CppType: type, value: CppType) *ZigType { - if (comptime hasRef(ZigType)) { - // *WTF::String => Wtf.String{ = value}, via casting instead of copying - if (comptime @typeInfo(CppType) == .Pointer and @typeInfo(ZigType) != .Pointer) { - return @bitCast(ZigType, @ptrToInt(value)); - } - } - - return @as(ZigType, value); - } - - pub fn symbolName(comptime typeName: []const u8) []const u8 { - return comptime std.fmt.comptimePrint("{s}__{s}__{s}", .{ namespace, name, typeName }); - } - - pub fn exportFunctions(comptime Functions: anytype) [std.meta.fieldNames(@TypeOf(Functions)).len]StaticExport { - const FunctionsType = @TypeOf(Functions); - return comptime brk: { - var functions: [std.meta.fieldNames(FunctionsType).len]StaticExport = undefined; - for (std.meta.fieldNames(FunctionsType)) |fn_name, i| { - const Function = @TypeOf(@field(Functions, fn_name)); - if (@typeInfo(Function) != .Fn) { - @compileError("Expected " ++ @typeName(Parent) ++ "." ++ @typeName(Function) ++ " to be a function but received " ++ @tagName(@typeInfo(Function))); - } - var Fn: std.builtin.TypeInfo.Fn = @typeInfo(Function).Fn; - if (Fn.calling_convention != .C) { - @compileError("Expected " ++ @typeName(Parent) ++ "." ++ @typeName(Function) ++ " to have a C Calling Convention."); - } - - const export_name = symbolName(fn_name); - functions[i] = StaticExport{ - .Type = Function, - .symbol_name = export_name, - .local_name = fn_name, - .Parent = Parent, - }; - } - - break :brk functions; - }; - } - - pub inline fn zigFn(comptime typeName: []const u8, args: anytype) (@typeInfo(@TypeOf(@field(Parent, typeName))).Fn.return_type orelse void) { - const identifier = symbolName(typeName); - const func = comptime @typeInfo(Parent).Struct.fields[std.meta.fieldIndex(Parent, typeName)].field_type; - const ReturnType = comptime @typeInfo(func).Fn.return_type orelse c_void; - - const Func: type = comptime brk: { - var FuncType: std.builtin.TypeInfo = @typeInfo(@TypeOf(func)); - var Fn: std.builtin.TypeInfo.Fn = FuncType.Fn; - - Fn.calling_convention = std.builtin.CallingConvention.C; - Fn.return_type = toCppType(Fn.return_type); - - const ArgsType = @TypeOf(args); - for (std.meta.fieldNames(args)) |field, i| { - Fn.args[i] = std.builtin.TypeInfo.FnArg{ - .is_generic = false, - .is_noalias = false, - .arg_type = @typeInfo(ArgsType).fields[i].field_type, - }; - } - FuncType.Fn = Fn; - break :brk @Type(FuncType); - }; - - comptime @export(Func, .{ .name = identifier }); - unreachable; - } - - pub inline fn cppFn(comptime typeName: []const u8, args: anytype) (ret: { - if (!@hasDecl(Parent, typeName)) { - @compileError(@typeName(Parent) ++ " is missing cppFn: " ++ typeName); - } - break :ret std.meta.declarationInfo(Parent, typeName).data.Fn.return_type; - }) { - if (comptime is_bindgen) { - unreachable; - } else { - const identifier = comptime std.fmt.comptimePrint("{s}__{s}__{s}", .{ namespace, name, typeName }); - const func = comptime @typeInfo(Parent).Struct.fields[std.meta.fieldIndex(Parent, typeName)].field_type; - const ReturnType = comptime @typeInfo(func).Fn.return_type orelse c_void; - - const Func: type = comptime brk: { - var FuncType: std.builtin.TypeInfo = @typeInfo(@TypeOf(func)); - var Fn: std.builtin.TypeInfo.Fn = FuncType.Fn; - - Fn.calling_convention = std.builtin.CallingConvention.C; - Fn.return_type = toCppType(Fn.return_type); - - const ArgsType = @TypeOf(args); - for (std.meta.fieldNames(args)) |field, i| { - Fn.args[i] = std.builtin.TypeInfo.FnArg{ - .is_generic = false, - .is_noalias = false, - .arg_type = @typeInfo(ArgsType).fields[i].field_type, - }; - } - FuncType.Fn = Fn; - break :brk @Type(FuncType); - }; - const Outgoing = comptime @extern(Func, std.builtin.ExternOptions{ .name = identifier }); - - return toZigType( - ReturnType, - @typeInfo(Func).Fn.return_type orelse void, - @call(.{}, Outgoing, args), - ); - } - } - }; -} +const Shimmer = @import("./shimmer.zig").Shimmer; pub const JSObject = packed struct { pub const shim = Shimmer("JSC", "JSObject", @This()); @@ -361,6 +178,75 @@ pub const JSPromiseRejectionOperation = enum(u32) { Handle = 1, }; +pub const ScriptArguments = packed struct { + pub const shim = Shimmer("Inspector", "ScriptArguments", @This()); + bytes: shim.Bytes, + const cppFn = shim.cppFn; + pub const include = "<JavaScriptCore/ScriptArguments.h>"; + pub const name = "Inspector::ScriptArguments"; + pub const namespace = "Inspector"; + + pub fn argumentAt(this: *const ScriptArguments, i: usize) JSValue { + return cppFn("argumentAt", .{ + this, + i, + }); + } + pub fn argumentCount(this: *const ScriptArguments) usize { + return cppFn("argumentCount", .{ + this, + }); + } + pub fn getFirstArgumentAsString(this: *const ScriptArguments) String { + return cppFn("getFirstArgumentAsString", .{ + this, + }); + } + + pub fn isEqual(this: *const ScriptArguments, other: *const ScriptArguments) bool { + return cppFn("isEqual", .{ this, other }); + } + + pub fn release(this: *ScriptArguments) void { + return cppFn("release", .{this}); + } + + pub const Extern = [_][]const u8{ + "argumentAt", + "argumentCount", + "getFirstArgumentAsString", + "isEqual", + "release", + }; +}; + +const EmptyGlobalInterface = struct { + pub fn import(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: *JSString, referrer: JSValue, origin: *const SourceOrigin) callconv(.C) *JSInternalPromise { + return JSInternalPromise.rejectedPromise(global, JSValue.jsUndefined()); + } + const slice = "hello.js"; + pub fn resolve(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: JSValue, value: JSValue, origin: *const SourceOrigin) callconv(.C) Identifier { + return Identifier.fromSlice(global.vm(), &slice, slice.len); + } + pub fn fetch(global: *JSGlobalObject, loader: *JSModuleLoader, value1: JSValue, value2: JSValue, value3: JSValue) callconv(.C) *JSInternalPromise { + return JSInternalPromise.rejectedPromise(global, JSValue.jsUndefined()); + } + pub fn eval(global: *JSGlobalObject, loader: *JSModuleLoader, key: JSValue, moduleRecordValue: JSValue, scriptFetcher: JSValue, awaitedValue: JSValue, resumeMode: JSValue) callconv(.C) JSValue { + return JSValue.jsUndefined(); + } + pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue { + return JSValue.jsUndefined(); + } + + pub fn reportUncaughtException(global: *JSGlobalObject, exception: *Exception) callconv(.C) JSValue { + return JSValue.jsUndefined(); + } + + pub fn createImportMetaProperties(global: *JSGlobalObject, loader: *JSModuleLoader, obj: JSValue, record: *JSModuleRecord, specifier: JSValue) callconv(.C) JSValue { + return JSValue.jsUndefined(); + } +}; + pub const ZigGlobalObject = packed struct { pub const shim = Shimmer("Zig", "GlobalObject", @This()); bytes: shim.Bytes, @@ -368,31 +254,56 @@ pub const ZigGlobalObject = packed struct { pub const name = "Zig::GlobalObject"; pub const include = "\"ZigGlobalObject.h\""; pub const namespace = shim.namespace; + pub const Interface: type = std.meta.globalOption("JSGlobalObject", type) orelse EmptyGlobalInterface; + + pub fn create(vm: ?*VM, console: *ZigConsoleClient) *JSGlobalObject { + return shim.cppFn("create", .{ vm, console }); + } + + pub fn import(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: *JSString, referrer: JSValue, origin: *const SourceOrigin) callconv(.C) *JSInternalPromise { + // if (comptime is_bindgen) { + // unreachable; + // } - pub fn import(global: *JSGlobalObject, loader: *JSModuleLoader, string: *JSString, value: JSValue, origin: *const SourceOrigin) callconv(.C) *JSInternalPromise { + return @call(.{ .modifier = .always_inline }, Interface.import, .{ global, loader, specifier, referrer, origin }); + } + pub fn resolve(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: JSValue, value: JSValue, origin: *const SourceOrigin) callconv(.C) Identifier { if (comptime is_bindgen) { unreachable; } + return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, loader, specifier, value, origin }); } - pub fn resolve(global: *JSGlobalObject, loader: *JSModuleLoader, string: *JSString, value: JSValue, origin: *const SourceOrigin) callconv(.C) *const Identifier { + pub fn fetch(global: *JSGlobalObject, loader: *JSModuleLoader, value1: JSValue, value2: JSValue, value3: JSValue) callconv(.C) *JSInternalPromise { if (comptime is_bindgen) { unreachable; } + return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, loader, value1, value2, value3 }); } - pub fn fetch(global: *JSGlobalObject, loader: *JSModuleLoader, value1: JSValue, value2: JSValue, value3: JSValue) callconv(.C) *JSInternalPromise { + pub fn eval(global: *JSGlobalObject, loader: *JSModuleLoader, key: JSValue, moduleRecordValue: JSValue, scriptFetcher: JSValue, awaitedValue: JSValue, resumeMode: JSValue) callconv(.C) JSValue { if (comptime is_bindgen) { unreachable; } + @call(.{ .modifier = .always_inline }, Interface.eval, .{ global, loader, key, moduleRecordValue, scriptFetcher, awaitedValue, resumeMode }); } - pub fn eval(global: *JSGlobalObject, loader: *JSModuleLoader, key: JSValue, moduleRecordValue: JSValue, scriptFetcher: JSValue, awaitedValue: JSValue, resumeMode: JSValue) callconv(.C) JSValue { + pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue { if (comptime is_bindgen) { unreachable; } + return @call(.{ .modifier = .always_inline }, Interface.promiseRejectionTracker, .{ global, promise, rejection }); } - pub fn reportUncaughtException(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue { + + pub fn reportUncaughtException(global: *JSGlobalObject, exception: *Exception) callconv(.C) JSValue { if (comptime is_bindgen) { unreachable; } + return @call(.{ .modifier = .always_inline }, Interface.reportUncaughtException, .{ global, exception }); + } + + pub fn createImportMetaProperties(global: *JSGlobalObject, loader: *JSModuleLoader, obj: JSValue, record: *JSModuleRecord, specifier: JSValue) callconv(.C) JSValue { + if (comptime is_bindgen) { + unreachable; + } + return @call(.{ .modifier = .always_inline }, Interface.createImportMetaProperties, .{ global, loader, obj, record, specifier }); } pub const Export = shim.exportFunctions(.{ @@ -400,15 +311,127 @@ pub const ZigGlobalObject = packed struct { .@"resolve" = resolve, .@"fetch" = fetch, .@"eval" = eval, + .@"promiseRejectionTracker" = promiseRejectionTracker, .@"reportUncaughtException" = reportUncaughtException, + .@"createImportMetaProperties" = createImportMetaProperties, }); + pub const Extern = [_][]const u8{"create"}; + comptime { @export(import, .{ .name = Export[0].symbol_name }); @export(resolve, .{ .name = Export[1].symbol_name }); @export(fetch, .{ .name = Export[2].symbol_name }); @export(eval, .{ .name = Export[3].symbol_name }); - @export(reportUncaughtException, .{ .name = Export[4].symbol_name }); + @export(promiseRejectionTracker, .{ .name = Export[4].symbol_name }); + @export(reportUncaughtException, .{ .name = Export[5].symbol_name }); + @export(createImportMetaProperties, .{ .name = Export[6].symbol_name }); + } +}; + +pub const ZigConsoleClient = packed struct { + pub const shim = Shimmer("Zig", "ConsoleClient", @This()); + pub const Type = *c_void; + pub const name = "Zig::ConsoleClient"; + pub const include = "\"ZigConsoleClient.h\""; + pub const namespace = shim.namespace; + pub const Counter = struct { + // if it turns out a hash table is a better idea we'll do that later + pub const Entry = struct { + hash: u32, + count: u32, + + pub const List = std.MultiArrayList(Entry); + }; + counts: Entry.List, + allocator: *std.mem.Allocator, + }; + + pub fn messageWithTypeAndLevel( + message_type: u32, + message_level: u32, + global: *JSGlobalObject, + args: *ScriptArguments, + ) callconv(.C) void { + var i: usize = 0; + const len = args.argumentCount(); + defer args.release(); + defer Output.flush(); + var writer = Output.writer(); + while (i < len) : (i += 1) { + var str = args.argumentAt(i).toWTFString(global); + writer.writeAll(str.slice()) catch {}; + } + } + pub fn count(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn countReset(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn time(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn timeLog(global: *JSGlobalObject, chars: [*]const u8, len: usize, args: *ScriptArguments) callconv(.C) void {} + pub fn timeEnd(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn profile(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn profileEnd(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn takeHeapSnapshot(global: *JSGlobalObject, chars: [*]const u8, len: usize) callconv(.C) void {} + pub fn timeStamp(global: *JSGlobalObject, args: *ScriptArguments) callconv(.C) void {} + pub fn record(global: *JSGlobalObject, args: *ScriptArguments) callconv(.C) void {} + pub fn recordEnd(global: *JSGlobalObject, args: *ScriptArguments) callconv(.C) void {} + pub fn screenshot(global: *JSGlobalObject, args: *ScriptArguments) callconv(.C) void {} + + pub const Export = shim.exportFunctions(.{ + .@"messageWithTypeAndLevel" = messageWithTypeAndLevel, + .@"count" = count, + .@"countReset" = countReset, + .@"time" = time, + .@"timeLog" = timeLog, + .@"timeEnd" = timeEnd, + .@"profile" = profile, + .@"profileEnd" = profileEnd, + .@"takeHeapSnapshot" = takeHeapSnapshot, + .@"timeStamp" = timeStamp, + .@"record" = record, + .@"recordEnd" = recordEnd, + .@"screenshot" = screenshot, + }); + + comptime { + @export(messageWithTypeAndLevel, .{ + .name = Export[0].symbol_name, + }); + @export(count, .{ + .name = Export[1].symbol_name, + }); + @export(countReset, .{ + .name = Export[2].symbol_name, + }); + @export(time, .{ + .name = Export[3].symbol_name, + }); + @export(timeLog, .{ + .name = Export[4].symbol_name, + }); + @export(timeEnd, .{ + .name = Export[5].symbol_name, + }); + @export(profile, .{ + .name = Export[6].symbol_name, + }); + @export(profileEnd, .{ + .name = Export[7].symbol_name, + }); + @export(takeHeapSnapshot, .{ + .name = Export[8].symbol_name, + }); + @export(timeStamp, .{ + .name = Export[9].symbol_name, + }); + @export(record, .{ + .name = Export[10].symbol_name, + }); + @export(recordEnd, .{ + .name = Export[11].symbol_name, + }); + @export(screenshot, .{ + .name = Export[12].symbol_name, + }); } }; @@ -1225,7 +1248,10 @@ pub const String = packed struct { }); } - pub const slice = SliceFn(@This()); + pub fn slice(this: *String) []const u8 { + const len = this.length(); + return if (len > 0) this.characters8()[0..len] else ""; + } pub const Extern = [_][]const u8{ "is8Bit", @@ -1375,6 +1401,10 @@ pub const JSValue = enum(i64) { return cppFn("toString", .{ this, globalThis }); } + pub fn toWTFString(this: JSValue, globalThis: *JSGlobalObject) String { + return cppFn("toWTFString", .{ this, globalThis }); + } + // On exception, this returns null, to make exception checks faster. pub fn toStringOrNull(this: JSValue, globalThis: *JSGlobalObject) *JSString { return cppFn("toStringOrNull", .{ this, globalThis }); @@ -1425,7 +1455,7 @@ pub const JSValue = enum(i64) { }); } - pub const Extern = [_][]const u8{ "hasProperty", "getPropertyNames", "getDirect", "putDirect", "get", "getIfExists", "encode", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell" }; + pub const Extern = [_][]const u8{ "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "get", "getIfExists", "encode", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell" }; }; pub const PropertyName = packed struct { @@ -1674,17 +1704,31 @@ pub const CallFrame = packed struct { call_frame, }); } + + pub inline fn setThisValue(call_frame: *CallFrame, new_this: JSValue) ?JSValue { + return cppFn("setThisValue", .{ + call_frame, + new_this, + }); + } pub inline fn newTarget(call_frame: *const CallFrame) ?JSValue { return cppFn("newTarget", .{ call_frame, }); } + + pub inline fn setNewTarget(call_frame: *CallFrame, target: JSValue) ?JSValue { + return cppFn("setNewTarget", .{ + call_frame, + target, + }); + } pub inline fn jsCallee(call_frame: *const CallFrame) *JSObject { return cppFn("jsCallee", .{ call_frame, }); } - pub const Extern = [_][]const u8{ "argumentsCount", "uncheckedArgument", "argument", "thisValue", "newTarget", "jsCallee" }; + pub const Extern = [_][]const u8{ "argumentsCount", "uncheckedArgument", "argument", "thisValue", "newTarget", "jsCallee", "setNewTarget", "setThisValue" }; }; // pub const WellKnownSymbols = packed struct { @@ -1956,28 +2000,44 @@ pub const StringView = packed struct { pub const Cpp = struct { pub const Function = fn ( globalObject: *JSGlobalObject, - callframe: *CallFrame, - ) *EncodedJSValue; + callframe: CallFrame, + ) callconv(.C) JSValue; pub const Getter = fn ( + ctx: ?*c_void, globalObject: *JSGlobalObject, - this: *EncodedJSValue, - propertyName: *PropertyName, - ) *EncodedJSValue; + this: EncodedJSValue, + propertyName: PropertyName, + ) callconv(.C) JSValue; pub const Setter = fn ( + ctx: ?*c_void, globalObject: *JSGlobalObject, - this: *EncodedJSValue, - value: EncodedJSValue, - propertyName: *PropertyName, - ) bool; + this: JSValue, + value: JSValue, + propertyName: PropertyName, + ) callconv(.C) bool; pub const Tag = enum { Callback, Constructor, - Getter, - Setter, + Attribute, + Static, + }; + + pub const Attribute = struct { + getter: ?StaticExport = null, + setter: ?StaticExport = null, + read_only: bool = false, + enumerable: bool = false, }; - pub const LUTAttribute = enum { + pub const Static = union { + String: []const u8, + Number: u16, + }; + + pub const Callback = StaticExport; + + pub const LUTType = enum { Function, Accessor, CellProperty, @@ -1985,13 +2045,355 @@ pub const Cpp = struct { PropertyCallback, }; - pub const ClassDefinition = struct { name: []const u8, hostFunctions: []Host }; + 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 const ZigValue = union(Tag) { - Callback: Function, - Constructor: Function, - Getter: Getter, - Setter: Setter, + // pub fn finalize(this: *BaseType, global: *JSGlobalObject) JSValue {} + // }; + // } }; }; pub const Callback = struct { @@ -2018,7 +2420,7 @@ const AsyncGeneratorPrototype = _JSCellStub("AsyncGeneratorPrototype"); const AsyncGeneratorFunctionPrototype = _JSCellStub("AsyncGeneratorFunctionPrototype"); pub fn SliceFn(comptime Type: type) type { const SliceStruct = struct { - pub fn slice(this: *Type) []const u8 { + pub fn slice(this: *const Type) []const u8 { if (this.isEmpty()) { return ""; } diff --git a/src/javascript/jsc/bindings/header-gen.zig b/src/javascript/jsc/bindings/header-gen.zig index 452c5d67c..15b13b4aa 100644 --- a/src/javascript/jsc/bindings/header-gen.zig +++ b/src/javascript/jsc/bindings/header-gen.zig @@ -572,8 +572,11 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type { switch (_decls.data) { .Type => |Type| { @setEvalBranchQuota(99999); - - if (@hasDecl(Type, "Extern") or @hasDecl(Type, "Export")) { + const is_container_type = switch (@typeInfo(Type)) { + .Opaque, .Struct => true, + else => false, + }; + if (is_container_type and (@hasDecl(Type, "Extern") or @hasDecl(Type, "Export"))) { const identifier = comptime std.fmt.comptimePrint("{s}_{s}", .{ Type.shim.name, Type.shim.namespace }); if (!bufset.contains(identifier)) { self.startFile( diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index 61b4d2f87..c8c0e7b16 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1626933952 +//-- AUTOGENERATED FILE -- 1627163531 #pragma once #include <stddef.h> @@ -31,6 +31,14 @@ extern "C" const size_t JSC__JSCell_object_align_ = alignof(JSC::JSCell); extern "C" const size_t JSC__JSString_object_size_ = sizeof(JSC::JSString); extern "C" const size_t JSC__JSString_object_align_ = alignof(JSC::JSString); +#ifndef INCLUDED__JavaScriptCore_ScriptArguments_h_ +#define INCLUDED__JavaScriptCore_ScriptArguments_h_ +#include <JavaScriptCore/ScriptArguments.h> +#endif + +extern "C" const size_t Inspector__ScriptArguments_object_size_ = sizeof(Inspector::ScriptArguments); +extern "C" const size_t Inspector__ScriptArguments_object_align_ = alignof(Inspector::ScriptArguments); + #ifndef INCLUDED__ZigGlobalObject_h_ #define INCLUDED__ZigGlobalObject_h_ #include "ZigGlobalObject.h" @@ -39,6 +47,14 @@ extern "C" const size_t JSC__JSString_object_align_ = alignof(JSC::JSString); extern "C" const size_t Zig__GlobalObject_object_size_ = sizeof(Zig::GlobalObject); extern "C" const size_t Zig__GlobalObject_object_align_ = alignof(Zig::GlobalObject); +#ifndef INCLUDED__ZigConsoleClient_h_ +#define INCLUDED__ZigConsoleClient_h_ +#include "ZigConsoleClient.h" +#endif + +extern "C" const size_t Zig__ConsoleClient_object_size_ = sizeof(Zig::ConsoleClient); +extern "C" const size_t Zig__ConsoleClient_object_align_ = alignof(Zig::ConsoleClient); + #ifndef INCLUDED__DefaultGlobal_h_ #define INCLUDED__DefaultGlobal_h_ #include "DefaultGlobal.h" @@ -127,14 +143,6 @@ extern "C" const size_t WTF__URL_object_align_ = alignof(WTF::URL); extern "C" const size_t WTF__String_object_size_ = sizeof(WTF::String); extern "C" const size_t WTF__String_object_align_ = alignof(WTF::String); -#ifndef INCLUDED__JavaScriptCore_JSValue_h_ -#define INCLUDED__JavaScriptCore_JSValue_h_ -#include <JavaScriptCore/JSValue.h> -#endif - -extern "C" const size_t JSC__JSValue_object_size_ = sizeof(JSC::JSValue); -extern "C" const size_t JSC__JSValue_object_align_ = alignof(JSC::JSValue); - #ifndef INCLUDED__JavaScriptCore_PropertyName_h_ #define INCLUDED__JavaScriptCore_PropertyName_h_ #include <JavaScriptCore/PropertyName.h> @@ -215,8 +223,8 @@ extern "C" const size_t WTF__ExternalStringImpl_object_align_ = alignof(WTF::Ext extern "C" const size_t WTF__StringView_object_size_ = sizeof(WTF::StringView); extern "C" const size_t WTF__StringView_object_align_ = alignof(WTF::StringView); -const size_t sizes[25] = {sizeof(JSC::JSObject), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Wundle::DefaultGlobal), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::CallFrame), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView)}; +const size_t sizes[26] = {sizeof(JSC::JSObject), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(Zig::GlobalObject), sizeof(Wundle::DefaultGlobal), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::CallFrame), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView)}; -const char* names[25] = {"JSC__JSObject", "JSC__JSCell", "JSC__JSString", "Wundle__DefaultGlobal", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__CallFrame", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView"}; +const char* names[26] = {"JSC__JSObject", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "Zig__GlobalObject", "Wundle__DefaultGlobal", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__CallFrame", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView"}; -const size_t aligns[25] = {alignof(JSC::JSObject), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Wundle::DefaultGlobal), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::CallFrame), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView)}; +const size_t aligns[26] = {alignof(JSC::JSObject), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(Zig::GlobalObject), alignof(Wundle::DefaultGlobal), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::CallFrame), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView)}; diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index 282a63333..b5a96ec37 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1626933952 +//-- AUTOGENERATED FILE -- 1627163531 #pragma once #include <stddef.h> @@ -38,9 +38,9 @@ typedef struct Wundle__DefaultGlobal Wundle__DefaultGlobal; // Wundle::DefaultGlobal typedef struct JSC__JSFunction JSC__JSFunction; // JSC::JSFunction typedef struct JSC__ArrayPrototype JSC__ArrayPrototype; // JSC::ArrayPrototype - typedef struct JSC__AsyncFunctionPrototype JSC__AsyncFunctionPrototype; // JSC::AsyncFunctionPrototype - typedef struct JSC__JSPromise JSC__JSPromise; // JSC::JSPromise typedef struct JSC__Identifier JSC__Identifier; // JSC::Identifier + typedef struct JSC__JSPromise JSC__JSPromise; // JSC::JSPromise + typedef struct JSC__AsyncFunctionPrototype JSC__AsyncFunctionPrototype; // JSC::AsyncFunctionPrototype typedef struct JSC__SetIteratorPrototype JSC__SetIteratorPrototype; // JSC::SetIteratorPrototype typedef struct JSC__SourceCode JSC__SourceCode; // JSC::SourceCode typedef struct JSC__JSCell JSC__JSCell; // JSC::JSCell @@ -54,8 +54,10 @@ typedef struct JSC__IteratorPrototype JSC__IteratorPrototype; // JSC::IteratorPrototype typedef struct JSC__JSInternalPromise JSC__JSInternalPromise; // JSC::JSInternalPromise typedef struct JSC__FunctionPrototype JSC__FunctionPrototype; // JSC::FunctionPrototype + typedef struct Inspector__ScriptArguments Inspector__ScriptArguments; // Inspector::ScriptArguments typedef struct JSC__Exception JSC__Exception; // JSC::Exception typedef struct JSC__JSString JSC__JSString; // JSC::JSString + typedef struct Zig__ConsoleClient Zig__ConsoleClient; // Zig::ConsoleClient typedef struct JSC__ObjectPrototype JSC__ObjectPrototype; // JSC::ObjectPrototype typedef struct JSC__CallFrame JSC__CallFrame; // JSC::CallFrame typedef struct JSC__MapIteratorPrototype JSC__MapIteratorPrototype; // JSC::MapIteratorPrototype @@ -82,6 +84,7 @@ typedef struct bJSC__JSGlobalObject { char bytes[2464]; } bJSC__JSGlobalObject; typedef struct bJSC__JSCell { char bytes[8]; } bJSC__JSCell; typedef struct bJSC__JSLock { char bytes[40]; } bJSC__JSLock; + typedef struct bInspector__ScriptArguments { char bytes[32]; } bInspector__ScriptArguments; typedef struct bWundle__DefaultGlobal { char bytes[2464]; } bWundle__DefaultGlobal; typedef struct bJSC__JSInternalPromise { char bytes[32]; } bJSC__JSInternalPromise; typedef struct bJSC__JSObject { char bytes[16]; } bJSC__JSObject; @@ -99,8 +102,8 @@ class JSObject; class AsyncIteratorPrototype; class AsyncGeneratorFunctionPrototype; - class JSPromise; class Identifier; + class JSPromise; class RegExpPrototype; class AsyncFunctionPrototype; class CatchScope; @@ -136,6 +139,12 @@ namespace Wundle { class DefaultGlobal; } + namespace Inspector { + class ScriptArguments; + } + namespace Zig { + class ConsoleClient; + } typedef int64_t JSC__JSValue; using JSC__JSCell = JSC::JSCell; @@ -148,8 +157,8 @@ using JSC__JSObject = JSC::JSObject; using JSC__AsyncIteratorPrototype = JSC::AsyncIteratorPrototype; using JSC__AsyncGeneratorFunctionPrototype = JSC::AsyncGeneratorFunctionPrototype; - using JSC__JSPromise = JSC::JSPromise; using JSC__Identifier = JSC::Identifier; + using JSC__JSPromise = JSC::JSPromise; using JSC__RegExpPrototype = JSC::RegExpPrototype; using JSC__AsyncFunctionPrototype = JSC::AsyncFunctionPrototype; using JSC__CatchScope = JSC::CatchScope; @@ -180,6 +189,8 @@ using WTF__StringView = WTF::StringView; using WTF__ExternalStringImpl = WTF::ExternalStringImpl; using Wundle__DefaultGlobal = Wundle::DefaultGlobal; + using Inspector__ScriptArguments = Inspector::ScriptArguments; + using Zig__ConsoleClient = Zig::ConsoleClient; #endif @@ -206,13 +217,40 @@ CPP_DECL size_t JSC__JSString__length(const JSC__JSString* arg0); CPP_DECL JSC__JSObject* JSC__JSString__toObject(JSC__JSString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL bWTF__String JSC__JSString__value(JSC__JSString* arg0, JSC__JSGlobalObject* arg1); +#pragma mark - Inspector::ScriptArguments + +CPP_DECL JSC__JSValue Inspector__ScriptArguments__argumentAt(const Inspector__ScriptArguments* arg0, size_t arg1); +CPP_DECL size_t Inspector__ScriptArguments__argumentCount(const Inspector__ScriptArguments* arg0); +CPP_DECL bWTF__String Inspector__ScriptArguments__getFirstArgumentAsString(const Inspector__ScriptArguments* arg0); +CPP_DECL bool Inspector__ScriptArguments__isEqual(const Inspector__ScriptArguments* arg0, const Inspector__ScriptArguments* arg1); +CPP_DECL void Inspector__ScriptArguments__release(Inspector__ScriptArguments* arg0); + #pragma mark - Zig::GlobalObject +CPP_DECL JSC__JSGlobalObject* Zig__GlobalObject__create(JSC__VM* arg0, Zig__ConsoleClient* arg1); +ZIG_DECL JSC__JSValue Zig__GlobalObject__createImportMetaProperties(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSModuleRecord* arg3, JSC__JSValue JSValue4); ZIG_DECL JSC__JSValue Zig__GlobalObject__eval(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, JSC__JSValue JSValue4, JSC__JSValue JSValue5, JSC__JSValue JSValue6); ZIG_DECL JSC__JSInternalPromise* Zig__GlobalObject__fetch(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, JSC__JSValue JSValue4); ZIG_DECL JSC__JSInternalPromise* Zig__GlobalObject__import(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSString* arg2, JSC__JSValue JSValue3, const JSC__SourceOrigin* arg4); -ZIG_DECL JSC__JSValue Zig__GlobalObject__reportUncaughtException(JSC__JSGlobalObject* arg0, JSC__JSPromise* arg1, uint32_t JSPromiseRejectionOperation2); -ZIG_DECL const JSC__Identifier* Zig__GlobalObject__resolve(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSString* arg2, JSC__JSValue JSValue3, const JSC__SourceOrigin* arg4); +ZIG_DECL JSC__JSValue Zig__GlobalObject__promiseRejectionTracker(JSC__JSGlobalObject* arg0, JSC__JSPromise* arg1, uint32_t JSPromiseRejectionOperation2); +ZIG_DECL JSC__JSValue Zig__GlobalObject__reportUncaughtException(JSC__JSGlobalObject* arg0, JSC__Exception* arg1); +ZIG_DECL bJSC__Identifier Zig__GlobalObject__resolve(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, const JSC__SourceOrigin* arg4); + +#pragma mark - Zig::ConsoleClient + +ZIG_DECL void Zig__ConsoleClient__count(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__countReset(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__messageWithTypeAndLevel(uint32_t arg0, uint32_t arg1, JSC__JSGlobalObject* arg2, Inspector__ScriptArguments* arg3); +ZIG_DECL void Zig__ConsoleClient__profile(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__profileEnd(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__record(JSC__JSGlobalObject* arg0, Inspector__ScriptArguments* arg1); +ZIG_DECL void Zig__ConsoleClient__recordEnd(JSC__JSGlobalObject* arg0, Inspector__ScriptArguments* arg1); +ZIG_DECL void Zig__ConsoleClient__screenshot(JSC__JSGlobalObject* arg0, Inspector__ScriptArguments* arg1); +ZIG_DECL void Zig__ConsoleClient__takeHeapSnapshot(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__time(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__timeEnd(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2); +ZIG_DECL void Zig__ConsoleClient__timeLog(JSC__JSGlobalObject* arg0, const char* arg1, size_t arg2, Inspector__ScriptArguments* arg3); +ZIG_DECL void Zig__ConsoleClient__timeStamp(JSC__JSGlobalObject* arg0, Inspector__ScriptArguments* arg1); #pragma mark - Wundle::DefaultGlobal @@ -365,53 +403,6 @@ CPP_DECL bool WTF__String__isExternal(WTF__String* arg0); CPP_DECL bool WTF__String__isStatic(WTF__String* arg0); CPP_DECL size_t WTF__String__length(WTF__String* arg0); -#pragma mark - JSC::JSValue - -CPP_DECL JSC__JSCell* JSC__JSValue__asCell(JSC__JSValue JSValue0); -CPP_DECL double JSC__JSValue__asNumber(JSC__JSValue JSValue0); -CPP_DECL bJSC__JSObject JSC__JSValue__asObject(JSC__JSValue JSValue0); -CPP_DECL JSC__JSString* JSC__JSValue__asString(JSC__JSValue JSValue0); -CPP_DECL uint64_t JSC__JSValue__encode(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__eqlCell(JSC__JSValue JSValue0, JSC__JSCell* arg1); -CPP_DECL bool JSC__JSValue__eqlValue(JSC__JSValue JSValue0, JSC__JSValue JSValue1); -CPP_DECL JSC__JSValue JSC__JSValue__getPrototype(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL bool JSC__JSValue__isAnyInt(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isBigInt(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isBigInt32(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isBoolean(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isCell(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isCustomGetterSetter(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isError(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isGetterSetter(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isHeapBigInt(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isInt32AsAnyInt(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isNull(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isNumber(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isObject(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isPrimitive(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isString(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isSymbol(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isUInt32AsAnyInt(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isUndefined(JSC__JSValue JSValue0); -CPP_DECL bool JSC__JSValue__isUndefinedOrNull(JSC__JSValue JSValue0); -CPP_DECL JSC__JSValue JSC__JSValue__jsBoolean(bool arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsDoubleNumber(double arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNull(); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromChar(char arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromDouble(double arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromInt32(int32_t arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromInt64(int64_t arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromU16(uint16_t arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsNumberFromUint64(uint64_t arg0); -CPP_DECL JSC__JSValue JSC__JSValue__jsTDZValue(); -CPP_DECL JSC__JSValue JSC__JSValue__jsUndefined(); -CPP_DECL JSC__JSObject* JSC__JSValue__toObject(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL bJSC__Identifier JSC__JSValue__toPropertyKey(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL JSC__JSValue JSC__JSValue__toPropertyKeyValue(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL JSC__JSString* JSC__JSValue__toString(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL JSC__JSString* JSC__JSValue__toString(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); -CPP_DECL JSC__JSString* JSC__JSValue__toStringOrNull(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1); - #pragma mark - JSC::PropertyName CPP_DECL bool JSC__PropertyName__eqlToIdentifier(JSC__PropertyName* arg0, const JSC__Identifier* arg1); @@ -453,6 +444,8 @@ CPP_DECL JSC__JSValue JSC__CallFrame__argument(const JSC__CallFrame* arg0, uint1 CPP_DECL size_t JSC__CallFrame__argumentsCount(const JSC__CallFrame* arg0); CPP_DECL JSC__JSObject* JSC__CallFrame__jsCallee(const JSC__CallFrame* arg0); CPP_DECL JSC__JSValue JSC__CallFrame__newTarget(const JSC__CallFrame* arg0); +CPP_DECL JSC__JSValue JSC__CallFrame__setNewTarget(JSC__CallFrame* arg0, JSC__JSValue JSValue1); +CPP_DECL JSC__JSValue JSC__CallFrame__setThisValue(JSC__CallFrame* arg0, JSC__JSValue JSValue1); CPP_DECL JSC__JSValue JSC__CallFrame__thisValue(const JSC__CallFrame* arg0); CPP_DECL JSC__JSValue JSC__CallFrame__uncheckedArgument(const JSC__CallFrame* arg0, uint16_t arg1); diff --git a/src/javascript/jsc/bindings/helpers.h b/src/javascript/jsc/bindings/helpers.h new file mode 100644 index 000000000..c21f3fb3c --- /dev/null +++ b/src/javascript/jsc/bindings/helpers.h @@ -0,0 +1,71 @@ + +#include "headers.h" +#include "root.h" + +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/VM.h> + + +template<class CppType, typename ZigType> +class Wrap { +public: + Wrap(){ + }; + + Wrap(ZigType zig){ + result = zig; + cpp = static_cast<CppType*>(static_cast<void*>(&zig)); + }; + + Wrap(CppType _cpp){ + char* buffer = alignedBuffer(); + memcpy(buffer, std::move(reinterpret_cast<char*>(reinterpret_cast<void*>(&_cpp))), sizeof(CppType)); + cpp = reinterpret_cast<CppType*>(buffer); + }; + + + ~Wrap(){}; + + char* alignedBuffer() { + return result.bytes + alignof(CppType) - reinterpret_cast<intptr_t>(result.bytes) % alignof(CppType); + } + + ZigType result; + CppType* cpp; + + static ZigType wrap(CppType obj) { + return *static_cast<ZigType*>(static_cast<void*>(&obj)); + } + + static ZigType wrap(CppType* obj) { + return *static_cast<ZigType*>(static_cast<void*>(obj)); + } +}; + + + + + +template<class To, class From> +To cast(From v) +{ + return *static_cast<To*>(static_cast<void*>(v)); +} + +template<class To, class From> +To ccast(From v) +{ + return *static_cast<const To*>(static_cast<const void*>(v)); +} + +typedef JSC__JSValue (* NativeCallbackFunction)(void* arg0, JSC__JSGlobalObject* arg1, JSC__CallFrame* arg2); + +static const JSC::ArgList makeArgs(JSC__JSValue* v, size_t count) { + JSC::MarkedArgumentBuffer args = JSC::MarkedArgumentBuffer(); + args.ensureCapacity(count); + for (size_t i = 0; i < count; ++i) { + args.append(JSC::JSValue::decode(v[i])); + } + + return JSC::ArgList(args); +} diff --git a/src/javascript/jsc/bindings/imports.zig b/src/javascript/jsc/bindings/imports.zig index 8b1378917..e69de29bb 100644 --- a/src/javascript/jsc/bindings/imports.zig +++ b/src/javascript/jsc/bindings/imports.zig @@ -1 +0,0 @@ - diff --git a/src/javascript/jsc/bindings/objects.cpp b/src/javascript/jsc/bindings/objects.cpp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/javascript/jsc/bindings/objects.cpp diff --git a/src/javascript/jsc/bindings/objects.h b/src/javascript/jsc/bindings/objects.h new file mode 100644 index 000000000..083d6a9d8 --- /dev/null +++ b/src/javascript/jsc/bindings/objects.h @@ -0,0 +1,266 @@ +// #pragma once + +// #include "root.h" +// #include "headers.h" + +// #include <JavaScriptCore/JSObject.h> +// #include <JavaScriptCore/JSCInlines.h> +// #include <JavaScriptCore/InternalFunction.h> + +// namespace Zig { + +// class ModulePrototype final : public JSC::JSNonFinalObject { +// public: +// using Base = JSC::JSNonFinalObject; +// DECLARE_EXPORT_INFO; +// static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::ImplementsHasInstance | JSC::ImplementsDefaultHasInstance; +// static constexpr bool needsDestruction = true; + +// template<typename CellType, JSC::SubspaceAccess> +// static JSC::IsoSubspace* subspaceFor(JSC::VM& vm) +// { +// STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(Headers, Base); +// return &vm.plainObjectSpace; +// } + +// static ModulePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* zigBase) +// { +// ModulePrototype* object = new (NotNull, JSC::allocateCell<ModulePrototype>(vm.heap)) ModulePrototype(vm, structure); +// !!zigBase ? object->finishCreation(vm, globalObject, zigBase) : object->finishCreation(vm, globalObject); +// return object; +// } + + +// static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject&); +// static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject&); + +// 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()); +// } + +// void* m_zigBase; + +// private: +// ModulePrototype(JSC::VM&, JSC::Structure*) : Base(vm, structure) { +// m_zigBase = nullptr; +// }; +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*, void* zigBase); +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*); + +// }; + +// class ModuleExportsMap final : public JSC::JSNonFinalObject { +// public: +// using Base = JSC::JSNonFinalObject; +// DECLARE_EXPORT_INFO; +// static constexpr unsigned StructureFlags = Base::StructureFlags; +// static constexpr bool needsDestruction = true; + +// template<typename CellType, JSC::SubspaceAccess> +// static JSC::IsoSubspace* subspaceFor(JSC::VM& vm) +// { +// STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(Headers, Base); +// return &vm.plainObjectSpace; +// } + +// static ModulePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* zigBase) +// { +// ModulePrototype* object = new (NotNull, JSC::allocateCell<ModulePrototype>(vm.heap)) ModulePrototype(vm, structure); +// !!zigBase ? object->finishCreation(vm, globalObject, zigBase) : object->finishCreation(vm, globalObject); +// return object; +// } + + +// static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject&); +// static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject&); + +// 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()); +// } + +// void* m_zigBase; + +// private: +// ModulePrototype(JSC::VM&, JSC::Structure*) : Base(vm, structure) { +// m_zigBase = nullptr; +// }; +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*, void* zigBase); +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*); + +// }; + + +// } + + + +// namespace Zig { + +// class HeadersPrototype final : public JSC::JSNonFinalObject { +// public: +// using Base = JSC::JSNonFinalObject; +// DECLARE_EXPORT_INFO; +// static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::ImplementsHasInstance | JSC::ImplementsDefaultHasInstance; +// static constexpr bool needsDestruction = true; + +// template<typename CellType, JSC::SubspaceAccess> +// static JSC::IsoSubspace* subspaceFor(JSC::VM& vm) +// { +// STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(Headers, Base); +// return &vm.plainObjectSpace; +// } + +// static HeadersPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* zigBase) +// { +// HeadersPrototype* object = new (NotNull, JSC::allocateCell<HeadersPrototype>(vm.heap)) HeadersPrototype(vm, structure); +// !!zigBase ? object->finishCreation(vm, globalObject, zigBase) : object->finishCreation(vm, globalObject); +// return object; +// } + +// static HeadersPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) +// { +// HeadersPrototype* object = new (NotNull, JSC::allocateCell<HeadersPrototype>(vm.heap)) HeadersPrototype(vm, structure); +// object->finishCreation(vm, globalObject); +// return object; +// } + + +// JSC::JSValue get(JSC::JSGlobalObject&, JSC::JSValue); +// bool put(JSC::JSGlobalObject&, JSC::JSValue, JSC::JSValue); +// bool has(JSC::JSGlobalObject&, JSC::JSValue); +// void remove(JSC::JSGlobalObject&, JSC::JSValue); +// void clear(JSC::JSGlobalObject&, JSC::JSValue); + +// static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject&); +// static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject&); + +// 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()); +// } + +// void* m_zigBase; + +// private: +// HeadersPrototype(JSC::VM&, JSC::Structure*) : Base(vm, structure) { +// m_zigBase = nullptr; +// }; +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*, void* zigBase); +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*); + +// }; + + +// JSC_DECLARE_HOST_FUNCTION(headersFuncPrototypeGet); +// JSC_DECLARE_HOST_FUNCTION(headersFuncPrototypePut); +// JSC_DECLARE_HOST_FUNCTION(headersFuncPrototypeHas); +// JSC_DECLARE_HOST_FUNCTION(headersFuncPrototypeRemove); +// JSC_DECLARE_HOST_FUNCTION(headersFuncPrototypeClear); + +// class HeadersConstructor final : public JSC::InternalFunction { +// public: +// typedef InternalFunction Base; + +// static HeadersConstructor* create(JSC::VM& vm, JSC::Structure* structure, HeadersPrototype* mapPrototype) +// { +// HeadersConstructor* constructor = new (NotNull, JSC::allocateCell<HeadersConstructor>(vm.heap)) HeadersConstructor(vm, structure); +// constructor->finishCreation(vm, mapPrototype); +// return constructor; +// } + +// DECLARE_EXPORT_INFO; + +// static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) +// { +// return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); +// } + +// private: +// HeadersConstructor(JSC::VM&, JSC::Structure*); + +// void finishCreation(JSC::VM&, HeadersPrototype*); +// }; + +// JSC_DECLARE_HOST_FUNCTION(headersFuncConstructor); + + + +// class RequestConstructor final : public JSC::InternalFunction { +// public: +// typedef InternalFunction Base; + +// static RequestConstructor* create(JSC::VM& vm, JSC::Structure* structure, RequestPrototype* mapPrototype) +// { +// RequestConstructor* constructor = new (NotNull, JSC::allocateCell<RequestConstructor>(vm.heap)) RequestConstructor(vm, structure); +// constructor->finishCreation(vm, mapPrototype); +// return constructor; +// } + +// DECLARE_EXPORT_INFO; + +// static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) +// { +// return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); +// } + +// private: +// RequestConstructor(JSC::VM&, JSC::Structure*); + +// void finishCreation(JSC::VM&, RequestPrototype*); +// }; + +// JSC_DECLARE_HOST_FUNCTION(requestFuncConstructor); + +// class RequestPrototype final : public JSC::JSNonFinalObject { +// public: +// using Base = JSC::JSNonFinalObject; +// DECLARE_EXPORT_INFO; +// static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::ImplementsHasInstance | JSC::ImplementsDefaultHasInstance; +// static constexpr bool needsDestruction = true; + +// template<typename CellType, JSC::SubspaceAccess> +// static JSC::IsoSubspace* subspaceFor(JSC::VM& vm) +// { +// STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(Headers, Base); +// return &vm.plainObjectSpace; +// } + +// static RequestPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* zigBase) +// { +// RequestPrototype* object = new (NotNull, JSC::allocateCell<RequestPrototype>(vm.heap)) RequestPrototype(vm, structure); +// !!zigBase ? object->finishCreation(vm, globalObject, zigBase) : object->finishCreation(vm, globalObject); +// return object; +// } + +// static RequestPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) +// { +// RequestPrototype* object = new (NotNull, JSC::allocateCell<RequestPrototype>(vm.heap)) RequestPrototype(vm, structure); +// object->finishCreation(vm, globalObject); +// return object; +// } + +// static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject&); +// static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject&); + +// 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()); +// } + +// void* m_zigBase; + +// private: +// RequestPrototype(JSC::VM&, JSC::Structure*) : Base(vm, structure) { +// m_zigBase = nullptr; +// }; +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*, void* zigBase); +// void finishCreation(JSC::VM&, JSC::JSGlobalObject*); + +// }; + + + +// } + diff --git a/src/javascript/jsc/bindings/shimmer.zig b/src/javascript/jsc/bindings/shimmer.zig new file mode 100644 index 000000000..3f61dad96 --- /dev/null +++ b/src/javascript/jsc/bindings/shimmer.zig @@ -0,0 +1,186 @@ +const std = @import("std"); +const StaticExport = @import("./static_export.zig"); +const Sizes = @import("./sizes.zig"); +const is_bindgen: bool = std.meta.globalOption("bindgen", bool) orelse false; + +pub fn Shimmer(comptime _namespace: []const u8, comptime _name: []const u8, comptime Parent: type) type { + return struct { + pub const namespace = _namespace; + pub const name = _name; + + fn toCppType(comptime FromType: ?type) ?type { + return comptime brk: { + var NewReturnType = FromType orelse c_void; + + if (NewReturnType == c_void) { + break :brk FromType; + } + + var ReturnTypeInfo: std.builtin.TypeInfo = @typeInfo(FromType orelse c_void); + + if (ReturnTypeInfo == .Pointer and NewReturnType != *c_void) { + NewReturnType = ReturnTypeInfo.Pointer.child; + ReturnTypeInfo = @typeInfo(NewReturnType); + } + + switch (ReturnTypeInfo) { + .Union, + .Struct, + .Enum, + => { + if (@hasDecl(ReturnTypeInfo, "Type")) { + break :brk NewReturnType; + } + }, + else => {}, + } + + break :brk FromType; + }; + } + pub const align_of_symbol = std.fmt.comptimePrint("{s}__{s}_object_align_", .{ namespace, name }); + pub const size_of_symbol = std.fmt.comptimePrint("{s}__{s}_object_size_", .{ namespace, name }); + pub const byte_size = brk: { + const identifier = std.fmt.comptimePrint("{s}__{s}", .{ namespace, name }); + const align_symbol = std.fmt.comptimePrint("{s}__{s}_align", .{ namespace, name }); + if (@hasDecl(Sizes, identifier)) { + break :brk @field(Sizes, identifier); //+ @field(Sizes, align_symbol); + } else { + break :brk 0; + } + }; + pub const Bytes = [byte_size]u8; + + pub inline fn getConvertibleType(comptime ZigType: type) type { + if (@typeInfo(ZigType) == .Struct) { + const Struct: std.builtin.TypeInfo.Struct = ChildType.Struct; + for (Struct.fields) |field| { + if (std.mem.eql(u8, field.name, "ref")) { + return field.field_type; + } + } + } + + return ZigType; + } + + fn pointerChild(comptime Type: type) type { + if (@typeInfo(Type) == .Pointer) { + return @typeInfo(Type).Pointer.child_type; + } + + return Type; + } + + pub inline fn toZigType(comptime ZigType: type, comptime CppType: type, value: CppType) *ZigType { + if (comptime hasRef(ZigType)) { + // *WTF::String => Wtf.String{ = value}, via casting instead of copying + if (comptime @typeInfo(CppType) == .Pointer and @typeInfo(ZigType) != .Pointer) { + return @bitCast(ZigType, @ptrToInt(value)); + } + } + + return @as(ZigType, value); + } + + pub fn symbolName(comptime typeName: []const u8) []const u8 { + return comptime std.fmt.comptimePrint("{s}__{s}__{s}", .{ namespace, name, typeName }); + } + + pub fn exportFunctions(comptime Functions: anytype) [std.meta.fieldNames(@TypeOf(Functions)).len]StaticExport { + const FunctionsType = @TypeOf(Functions); + return comptime brk: { + var functions: [std.meta.fieldNames(FunctionsType).len]StaticExport = undefined; + for (std.meta.fieldNames(FunctionsType)) |fn_name, i| { + const Function = @TypeOf(@field(Functions, fn_name)); + if (@typeInfo(Function) != .Fn) { + @compileError("Expected " ++ @typeName(Parent) ++ "." ++ @typeName(Function) ++ " to be a function but received " ++ @tagName(@typeInfo(Function))); + } + var Fn: std.builtin.TypeInfo.Fn = @typeInfo(Function).Fn; + if (Fn.calling_convention != .C) { + @compileError("Expected " ++ @typeName(Parent) ++ "." ++ @typeName(Function) ++ " to have a C Calling Convention."); + } + + const export_name = symbolName(fn_name); + functions[i] = StaticExport{ + .Type = Function, + .symbol_name = export_name, + .local_name = fn_name, + .Parent = Parent, + }; + } + + break :brk functions; + }; + } + + pub inline fn zigFn(comptime typeName: []const u8, args: anytype) (@typeInfo(@TypeOf(@field(Parent, typeName))).Fn.return_type orelse void) { + const identifier = symbolName(typeName); + const func = comptime @typeInfo(Parent).Struct.fields[std.meta.fieldIndex(Parent, typeName)].field_type; + const ReturnType = comptime @typeInfo(func).Fn.return_type orelse c_void; + + const Func: type = comptime brk: { + var FuncType: std.builtin.TypeInfo = @typeInfo(@TypeOf(func)); + var Fn: std.builtin.TypeInfo.Fn = FuncType.Fn; + + Fn.calling_convention = std.builtin.CallingConvention.C; + Fn.return_type = toCppType(Fn.return_type); + + const ArgsType = @TypeOf(args); + for (std.meta.fieldNames(args)) |field, i| { + Fn.args[i] = std.builtin.TypeInfo.FnArg{ + .is_generic = false, + .is_noalias = false, + .arg_type = @typeInfo(ArgsType).fields[i].field_type, + }; + } + FuncType.Fn = Fn; + break :brk @Type(FuncType); + }; + + comptime @export(Func, .{ .name = identifier }); + unreachable; + } + + pub inline fn cppFn(comptime typeName: []const u8, args: anytype) (ret: { + if (!@hasDecl(Parent, typeName)) { + @compileError(@typeName(Parent) ++ " is missing cppFn: " ++ typeName); + } + break :ret std.meta.declarationInfo(Parent, typeName).data.Fn.return_type; + }) { + if (comptime is_bindgen) { + unreachable; + } else { + const identifier = comptime std.fmt.comptimePrint("{s}__{s}__{s}", .{ namespace, name, typeName }); + const func = comptime @typeInfo(Parent).Struct.fields[std.meta.fieldIndex(Parent, typeName)].field_type; + const ReturnType = comptime @typeInfo(func).Fn.return_type orelse c_void; + + const Func: type = comptime brk: { + var FuncType: std.builtin.TypeInfo = @typeInfo(@TypeOf(func)); + var Fn: std.builtin.TypeInfo.Fn = FuncType.Fn; + + Fn.calling_convention = std.builtin.CallingConvention.C; + Fn.return_type = toCppType(Fn.return_type); + + const ArgsType = @TypeOf(args); + for (std.meta.fieldNames(args)) |field, i| { + Fn.args[i] = std.builtin.TypeInfo.FnArg{ + .is_generic = false, + .is_noalias = false, + .arg_type = @typeInfo(ArgsType).fields[i].field_type, + }; + } + FuncType.Fn = Fn; + break :brk @Type(FuncType); + }; + const Outgoing = comptime @extern(Func, std.builtin.ExternOptions{ .name = identifier }); + + return toZigType( + ReturnType, + @typeInfo(Func).Fn.return_type orelse void, + @call(.{}, Outgoing, args), + ); + } + } + }; +} diff --git a/src/javascript/jsc/bindings/sizes.zig b/src/javascript/jsc/bindings/sizes.zig index 88cc96c12..ddee597de 100644 --- a/src/javascript/jsc/bindings/sizes.zig +++ b/src/javascript/jsc/bindings/sizes.zig @@ -1,4 +1,4 @@ -// Auto-generated by src/javascript/jsc/headergen/sizegen.cpp at 2021-07-21 22:39:1626932365. +// Auto-generated by src/javascript/jsc/headergen/sizegen.cpp at 2021-07-23 23:37:1627108668. // These are the byte sizes for the different object types with bindings in JavaScriptCore. // This allows us to safely return stack allocated C++ types to Zig. // It is only safe to do this when these sizes are correct. @@ -15,12 +15,14 @@ // Run "jsc-bindings-headers" twice because it uses these values in the output. That's how all the bJSC__.* types are created - from these values. pub const JSC__JSObject = 16; pub const JSC__JSObject_align = 8; -pub const JSC__JSMap = 56; -pub const JSC__JSMap_align = 8; pub const JSC__JSCell = 8; pub const JSC__JSCell_align = 4; pub const JSC__JSString = 16; pub const JSC__JSString_align = 8; +pub const Inspector__ScriptArguments = 32; +pub const Inspector__ScriptArguments_align = 8; +pub const Zig__GlobalObject = 2464; +pub const Zig__GlobalObject_align = 8; pub const Wundle__DefaultGlobal = 2464; pub const Wundle__DefaultGlobal_align = 8; pub const JSC__JSModuleLoader = 16; diff --git a/src/javascript/jsc/bindings/static_export.zig b/src/javascript/jsc/bindings/static_export.zig index a922ae96b..8c30587a0 100644 --- a/src/javascript/jsc/bindings/static_export.zig +++ b/src/javascript/jsc/bindings/static_export.zig @@ -7,3 +7,7 @@ Parent: type, pub fn Decl(comptime this: *const @This()) std.builtin.TypeInfo.Declaration { return comptime std.meta.declarationInfo(this.Parent, this.local_name); } + +pub fn wrappedName(comptime this: *const @This()) []const u8 { + return comptime "wrap" ++ this.symbol_name; +} diff --git a/src/javascript/jsc/headergen/sizegen.cpp b/src/javascript/jsc/headergen/sizegen.cpp index ecad3f2f3..ed43810e2 100644 --- a/src/javascript/jsc/headergen/sizegen.cpp +++ b/src/javascript/jsc/headergen/sizegen.cpp @@ -25,7 +25,7 @@ int main() { cout << "// Failure to do so will lead to undefined behavior and probably some frustrated people.\n"; cout << "// --- Regenerate this: --- \n"; cout << "// 1. \"make jsc-bindings-headers\"\n"; - cout << "// 2. \"make sizegen\"\n"; + cout << "// 2. \"makpe sizegen\"\n"; cout << "// 3. \"make jsc-bindings-headers\"\n"; cout << "// ------------------------\n"; cout << "// You can verify the numbers written in this file at runtime via the `extern`d types\n"; diff --git a/src/js_printer.zig b/src/js_printer.zig index fbdff279a..1ea436589 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -3828,6 +3828,7 @@ pub fn printAst( ) !usize { const PrinterType = NewPrinter(false, Writer, LinkerType, false, false); var writer = _writer; + var printer = try PrinterType.init( writer, &tree, diff --git a/src/main_javascript.zig b/src/main_javascript.zig index 5c1ed6141..b6aa7da08 100644 --- a/src/main_javascript.zig +++ b/src/main_javascript.zig @@ -19,7 +19,7 @@ const clap = @import("clap"); const bundler = @import("bundler.zig"); const fs = @import("fs.zig"); const NodeModuleBundle = @import("./node_module_bundle.zig").NodeModuleBundle; -const js = @import("javascript/jsc/javascript.zig"); +const js_bindings = @import("javascript/jsc/bindings/bindings.zig"); const allocators = @import("allocators.zig"); pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { if (MainPanicHandler.Singleton) |singleton| { @@ -365,19 +365,21 @@ pub const Cli = struct { var panicker = MainPanicHandler.init(&log); MainPanicHandler.Singleton = &panicker; - var args = try Arguments.parse(alloc.static, stdout, stderr); - // var serve_bundler = try bundler.ServeBundler.init(allocator, &log, args); - // var res = try serve_bundler.buildFile(&log, allocator, args.entry_points[0], std.fs.path.extension(args.entry_points[0])); - - // var results = try bundler.Bundler.bundle(allocator, &log, args); - // var file = results.output_files[0]; - var vm = try js.VirtualMachine.init(allocator, args, null, &log); - var resolved_entry_point = try vm.bundler.resolver.resolve( - vm.bundler.fs.top_level_dir, - vm.bundler.normalizeEntryPointPath(vm.bundler.options.entry_points[0]), - .entry_point, - ); - var exception: js.JSValueRef = null; - var result = try js.Module.loadFromResolveResult(vm, vm.global.ctx, resolved_entry_point, &exception); + // var args = try Arguments.parse(alloc.static, stdout, stderr); + // // var serve_bundler = try bundler.ServeBundler.init(allocator, &log, args); + // // var res = try serve_bundler.buildFile(&log, allocator, args.entry_points[0], std.fs.path.extension(args.entry_points[0])); + + // // var results = try bundler.Bundler.bundle(allocator, &log, args); + // // var file = results.output_files[0]; + // var vm = try js.VirtualMachine.init(allocator, args, null, &log); + // var resolved_entry_point = try vm.bundler.resolver.resolve( + // vm.bundler.fs.top_level_dir, + // vm.bundler.normalizeEntryPointPath(vm.bundler.options.entry_points[0]), + // .entry_point, + // ); + // var exception: js.JSValueRef = null; + // var result = try js.Module.loadFromResolveResult(vm, vm.global.ctx, resolved_entry_point, &exception); +js_bindings.ZigConsoleClient + js_bindings.ZigGlobalObject.create(vm: ?*VM, console: *ZigConsoleClient) } }; |