From 3d583f7246ae06b41843e5460bb5b5f94b7634c7 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Wed, 3 Apr 2024 11:27:38 +1100 Subject: [PATCH 1/2] size optimization attempt --- src/source/ComposerGenerator.scala | 4 ++-- src/source/YamlGenerator.scala | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/source/ComposerGenerator.scala b/src/source/ComposerGenerator.scala index 4008038e..ed180ff0 100644 --- a/src/source/ComposerGenerator.scala +++ b/src/source/ComposerGenerator.scala @@ -344,8 +344,8 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { for (t <- refs.interfaces.filter(t => t != withNs(Some(helperNamespace), helperClass(ident)))) { w.wl(s"${t}::registerSchema(resolve);") } - w.wl("static std::once_flag flag[2];") - w.wl("std::call_once(flag[resolve ? 1 : 0], [resolve] { djinni::composer::registerSchemaImpl(unresolvedSchema(), resolve); });") + w.wl("static bool flag[2] = {false, false};") + w.wl("if (std::exchange(flag[resolve ? 1 : 0], true) == false) { djinni::composer::registerSchemaImpl(unresolvedSchema(), resolve); }") } // type reference w.w(s"const ValueSchema& $helper::schemaRef()").braced { diff --git a/src/source/YamlGenerator.scala b/src/source/YamlGenerator.scala index 42924769..c61bdd87 100644 --- a/src/source/YamlGenerator.scala +++ b/src/source/YamlGenerator.scala @@ -72,9 +72,15 @@ class YamlGenerator(spec: Spec) extends Generator(spec) { w.wl("objcpp:").nested { write(w, objcpp(td)) } w.wl("java:").nested { write(w, java(td)) } w.wl("jni:").nested { write(w, jni(td)) } - w.wl("wasm:").nested { write(w, wasm(td)) } - w.wl("composer:").nested { write(w, composer(td)) } - w.wl("ts:").nested {write(w, ts(td)) } + if (spec.wasmOutFolder.isDefined) { + w.wl("wasm:").nested { write(w, wasm(td)) } + } + if (spec.composerOutFolder.isDefined) { + w.wl("composer:").nested { write(w, composer(td)) } + } + if (spec.wasmOutFolder.isDefined || spec.composerOutFolder.isDefined) { + w.wl("ts:").nested {write(w, ts(td)) } + } } private def write(w: IndentWriter, m: Map[String, Any]) { @@ -307,7 +313,7 @@ object YamlGenerator { nested(td, key)(subKey).toString } catch { case e: java.util.NoSuchElementException => { - println(s"Warning: in ${td.origin}, missing field $key/$subKey") + // println(s"Warning: in ${td.origin}, missing field $key/$subKey") "[unspecified]" } } From ee6e977b7d411e15da4a47beef9f84618055e3d2 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Wed, 3 Apr 2024 16:29:44 +1100 Subject: [PATCH 2/2] noexcept --- src/source/ComposerGenerator.scala | 22 +++---- support-lib/composer/Future_composer.hpp | 4 +- support-lib/composer/djinni_composer.cpp | 16 ++--- support-lib/composer/djinni_composer.hpp | 82 ++++++++++++------------ 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/source/ComposerGenerator.scala b/src/source/ComposerGenerator.scala index ed180ff0..81ec1935 100644 --- a/src/source/ComposerGenerator.scala +++ b/src/source/ComposerGenerator.scala @@ -195,7 +195,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { w.wl("static CppType toCpp(const ComposerType& v);") w.wl("static ComposerType fromCpp(const CppType& c);") w.wl - w.wl("static const Composer::ValueSchema& schema();") + w.wl("static const Composer::ValueSchema& schema() noexcept;") } }), (w => {})) writeCppFileGeneric(spec.composerOutFolder.get, helperNamespace(), composerFilenameStyle, spec.composerIncludePrefix) (ident.name, origin, refs.cpp, (w => { @@ -219,7 +219,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { } w.wl("return Value(o);") } - w.w(s"const ValueSchema& $helper::schema()").braced { + w.w(s"const ValueSchema& $helper::schema() noexcept").braced { //FIXME: _djinnin_record_namespace? w.wl(s"""static auto schema = ValueSchema::cls(STRING_LITERAL("${schemaTypeNameForRecord(ident)}"), false,""").bracedEnd(");") { for (f <- r.fields) { @@ -246,9 +246,9 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { val helper = helperClass(ident) writeHppFileGeneric(spec.composerOutFolder.get, helperNamespace(), composerFilenameStyle)(ident.name, origin, refs.hpp, Nil, (w => { w.w(s"struct $helper : ::djinni::composer::JsInterface<$cls, $helper>").bracedSemi { - w.wl("static void registerSchema(bool resolve);") - w.wl("static const Composer::ValueSchema& schemaRef();") - w.wl("static const Composer::ValueSchema& schema();") + w.wl("static void registerSchema(bool resolve) noexcept;") + w.wl("static const Composer::ValueSchema& schemaRef() noexcept;") + w.wl("static const Composer::ValueSchema& schema() noexcept;") // cpp marshal helper if (i.ext.cpp) { @@ -273,7 +273,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { //static methods val staticMethods = i.methods.filter(m => m.static) if (!staticMethods.isEmpty) { - w.wl("static void djinniInitStaticMethods(Composer::Ref m);") + w.wl("static void djinniInitStaticMethods(Composer::Ref m) noexcept;") } //TODO ??? @@ -327,7 +327,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { } } //value schema - w.w(s"static const ValueSchema& unresolvedSchema()").braced { + w.w(s"static const ValueSchema& unresolvedSchema() noexcept").braced { w.wl(s"static auto schema = ValueSchema::cls(schemaName(), true,").bracedEnd(");") { for (m <- i.methods.filter(m => !m.static)) { w.w(s"""ClassPropertySchema(STRING_LITERAL("${idJs.method(m.ident)}"), ValueSchema::function(${stubRetSchema(m)},""").bracedEnd(")),") { @@ -339,7 +339,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { } w.wl("return schema;") } - w.w(s"void $helper::registerSchema(bool resolve)").braced { + w.w(s"void $helper::registerSchema(bool resolve) noexcept").braced { //register dependent interfaces (params and return that are interfaces but not this one) for (t <- refs.interfaces.filter(t => t != withNs(Some(helperNamespace), helperClass(ident)))) { w.wl(s"${t}::registerSchema(resolve);") @@ -348,11 +348,11 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { w.wl("if (std::exchange(flag[resolve ? 1 : 0], true) == false) { djinni::composer::registerSchemaImpl(unresolvedSchema(), resolve); }") } // type reference - w.w(s"const ValueSchema& $helper::schemaRef()").braced { + w.w(s"const ValueSchema& $helper::schemaRef() noexcept").braced { w.wl("static auto ref = ValueSchema::typeReference(ValueSchemaTypeReference::named(schemaName()));") w.wl("return ref;") } - w.w(s"const ValueSchema& $helper::schema()").braced { + w.w(s"const ValueSchema& $helper::schema() noexcept").braced { w.wl(s"static auto schema = djinni::composer::getResolvedSchema<$helper>(schemaName());") w.wl("return schema;") } @@ -385,7 +385,7 @@ class ComposerGenerator(spec: Spec) extends Generator(spec) { val staticMethods = i.methods.filter(m => m.static && m.lang.js) if (!staticMethods.isEmpty) { // object for static methods - w.wl(s"void ${helper}::djinniInitStaticMethods(Ref m)").braced { + w.wl(s"void ${helper}::djinniInitStaticMethods(Ref m) noexcept").braced { w.wl(s"""auto unresolvedStaticSchema = ValueSchema::cls(STRING_LITERAL("${schemaTypeNameForStaticInterface(ident)}"), false,""").bracedEnd(");") { for (m <- staticMethods) { w.w(s"""ClassPropertySchema(STRING_LITERAL("${idJs.method(m.ident)}"), ValueSchema::function(${stubRetSchema(m)},""").bracedEnd(")),") { diff --git a/support-lib/composer/Future_composer.hpp b/support-lib/composer/Future_composer.hpp index f8f7a4ec..2f53a355 100644 --- a/support-lib/composer/Future_composer.hpp +++ b/support-lib/composer/Future_composer.hpp @@ -78,14 +78,14 @@ class FutureAdaptor template struct ExceptionHandlingTraits> { - static Composer::Value handleNativeException(const std::exception& e, const Composer::ValueFunctionCallContext& callContext) { + static Composer::Value handleNativeException(const std::exception& e, const Composer::ValueFunctionCallContext& callContext) noexcept { // store C++ exception in JS Error and raise in JS runtime auto msg = STRING_FORMAT("C++: {}", e.what()); auto composerPromise = Composer::makeShared(); composerPromise->fulfill(Composer::Result(Composer::Error(std::move(msg)))); return Composer::Value(composerPromise); } - static Composer::Value handleNativeException(const JsException& e, const Composer::ValueFunctionCallContext& callContext) { + static Composer::Value handleNativeException(const JsException& e, const Composer::ValueFunctionCallContext& callContext) noexcept { // JS error passthrough auto composerPromise = Composer::makeShared(); composerPromise->fulfill(Composer::Result(e.cause())); diff --git a/support-lib/composer/djinni_composer.cpp b/support-lib/composer/djinni_composer.cpp index 4cd9e758..30c4cae5 100644 --- a/support-lib/composer/djinni_composer.cpp +++ b/support-lib/composer/djinni_composer.cpp @@ -33,7 +33,7 @@ void checkForNull(void* ptr, const char* context) { } } -ValueSchema resolveSchema(const ValueSchema& unresolved, std::function registerSchemaFunc) { +ValueSchema resolveSchema(const ValueSchema& unresolved, std::function registerSchemaFunc) noexcept { registerSchemaFunc(); Composer::ValueSchemaTypeResolver resolver(Composer::ValueSchemaRegistry::sharedInstance().get()); auto result = resolver.resolveTypeReferences(unresolved); @@ -41,7 +41,7 @@ ValueSchema resolveSchema(const ValueSchema& unresolved, std::function r return result.moveValue(); } -void registerSchemaImpl(const ValueSchema& schema, bool resolve) { +void registerSchemaImpl(const ValueSchema& schema, bool resolve) noexcept { auto registry = ValueSchemaRegistry::sharedInstance(); if (!resolve) { registry->registerSchema(schema); @@ -54,35 +54,35 @@ void registerSchemaImpl(const ValueSchema& schema, bool resolve) { } } -Binary::CppType Binary::toCpp(const Binary::ComposerType& v) { +Binary::CppType Binary::toCpp(const Binary::ComposerType& v) noexcept { auto a = v.getTypedArrayRef(); auto buffer = a->getBuffer(); return CppType(buffer.begin(), buffer.end()); } -Binary::ComposerType Binary::fromCpp(const Binary::CppType& c) { +Binary::ComposerType Binary::fromCpp(const Binary::CppType& c) noexcept { auto bytes = makeShared(); bytes->assignData(c.data(), c.size()); auto va = makeShared(TypedArrayType::Uint8Array, bytes); return Value(va); } -const ValueSchema& Binary::schema() { +const ValueSchema& Binary::schema() noexcept { static auto schema = ValueSchema::valueTypedArray(); return schema; } -Date::CppType Date::toCpp(const Date::ComposerType& v) { +Date::CppType Date::toCpp(const Date::ComposerType& v) noexcept { auto millisecondsSinceEpoch = std::chrono::milliseconds(static_cast(v.toDouble())); return CppType(std::chrono::duration_cast(millisecondsSinceEpoch)); } -Date::ComposerType Date::fromCpp(const Date::CppType& c) { +Date::ComposerType Date::fromCpp(const Date::CppType& c) noexcept { auto millisecondsSinceEpoch = std::chrono::duration_cast(c.time_since_epoch()); return Composer::Value(static_cast(millisecondsSinceEpoch.count())); } -const ValueSchema& Date::schema() { +const ValueSchema& Date::schema() noexcept { static auto schema = ValueSchema::date(); return schema; } diff --git a/support-lib/composer/djinni_composer.hpp b/support-lib/composer/djinni_composer.hpp index 707af64b..a1589f3c 100644 --- a/support-lib/composer/djinni_composer.hpp +++ b/support-lib/composer/djinni_composer.hpp @@ -48,20 +48,20 @@ class JsException : public std::runtime_error { // Input must be an instanceof an Error Type JsException(Composer::Error e): std::runtime_error(e.toString()), _jsEx(std::move(e)) {} - const Composer::Error& cause() const { return _jsEx; } + const Composer::Error& cause() const noexcept { return _jsEx; } private: Composer::Error _jsEx; }; template struct ExceptionHandlingTraits { - static Composer::Value handleNativeException(const std::exception& e, const Composer::ValueFunctionCallContext& callContext) { + static Composer::Value handleNativeException(const std::exception& e, const Composer::ValueFunctionCallContext& callContext) noexcept { // store C++ exception in JS Error and raise in JS runtime auto msg = STRING_FORMAT("C++: {}", e.what()); callContext.getExceptionTracker().onError(Composer::Error(std::move(msg))); return Composer::Value::undefined(); } - static Composer::Value handleNativeException(const JsException& e, const Composer::ValueFunctionCallContext& callContext) { + static Composer::Value handleNativeException(const JsException& e, const Composer::ValueFunctionCallContext& callContext) noexcept { // JS error passthrough callContext.getExceptionTracker().onError(e.cause()); return Composer::Value::undefined(); @@ -69,8 +69,8 @@ struct ExceptionHandlingTraits { }; template -Composer::Value tsFunc(F&& f) { - return Composer::Value(Composer::makeShared([f = std::forward(f)] (const Composer::ValueFunctionCallContext& callContext) { +Composer::Value tsFunc(F&& f) noexcept { + return Composer::Value(Composer::makeShared([f = std::forward(f)] (const Composer::ValueFunctionCallContext& callContext) noexcept { try { return f(callContext); } @@ -85,12 +85,12 @@ Composer::Value tsFunc(F&& f) { void checkForNull(void* ptr, const char* context); -Composer::ValueSchema resolveSchema(const Composer::ValueSchema& unresolved, std::function registerSchemaFunc); +Composer::ValueSchema resolveSchema(const Composer::ValueSchema& unresolved, std::function registerSchemaFunc) noexcept; -void registerSchemaImpl(const Composer::ValueSchema& schema, bool resolve); +void registerSchemaImpl(const Composer::ValueSchema& schema, bool resolve) noexcept; template -Composer::ValueSchema getResolvedSchema(const Composer::StringBox& typeName) { +Composer::ValueSchema getResolvedSchema(const Composer::StringBox& typeName) noexcept { T::registerSchema(false); T::registerSchema(true); auto registry = Composer::ValueSchemaRegistry::sharedInstance(); @@ -104,7 +104,7 @@ template struct hasSchemaRef> : std::true_type { }; template -const Composer::ValueSchema& schemaOrRef() { +const Composer::ValueSchema& schemaOrRef() noexcept { if constexpr (hasSchemaRef::value) { return T::schemaRef(); } else { @@ -121,13 +121,13 @@ class Primitive { using Boxed = Primitive; - static CppType toCpp(const ComposerType& v) { + static CppType toCpp(const ComposerType& v) noexcept { return static_cast(v.to()); } - static ComposerType fromCpp(const CppType& c) { + static ComposerType fromCpp(const CppType& c) noexcept { return ComposerType(static_cast(c)); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::primitiveType(); return schema; } @@ -173,7 +173,7 @@ class WString { static ComposerType fromCpp(const CppType& c) { return ComposerType(Utf8Converter{}.to_bytes(c)); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::string(); return schema; } @@ -186,9 +186,9 @@ class Binary { using ComposerType = Composer::Value; using Boxed = Binary; - static CppType toCpp(const ComposerType& j); - static ComposerType fromCpp(const CppType& c); - static const Composer::ValueSchema& schema(); + static CppType toCpp(const ComposerType& j) noexcept; + static ComposerType fromCpp(const CppType& c) noexcept; + static const Composer::ValueSchema& schema() noexcept ; }; class Date { @@ -197,9 +197,9 @@ class Date { using ComposerType = Composer::Value; using Boxed = Date; - static CppType toCpp(const ComposerType& v); - static ComposerType fromCpp(const CppType& c); - static const Composer::ValueSchema& schema(); + static CppType toCpp(const ComposerType& v) noexcept; + static ComposerType fromCpp(const CppType& c) noexcept; + static const Composer::ValueSchema& schema() noexcept; }; template class OptionalType, class T> @@ -226,7 +226,7 @@ struct Optional { static ComposerType fromCpp(const typename C::CppOptType& cppOpt) { return T::Boxed::fromCppOpt(cppOpt); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = schemaOrRef().asOptional(); return schema; } @@ -242,7 +242,7 @@ class List { using ComposerType = Composer::Value; using Boxed = List; - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::array(schemaOrRef()); return schema; } @@ -291,7 +291,7 @@ class Set { } return Composer::Value(es6set); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::es6set(schemaOrRef()); return schema; } @@ -326,7 +326,7 @@ class Map { } return Composer::Value(es6Map); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::es6map(schemaOrRef(), schemaOrRef()); return schema; } @@ -337,7 +337,7 @@ class Void { using CppType = void; using ComposerType = Composer::Value; using Boxed = Void; - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::untyped(); return schema; } @@ -373,7 +373,7 @@ class Protobuf { return Composer::Value(array); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { constexpr std::array jsClassName = {JsClassName.data...}; static auto schema = Composer::ValueSchema::proto(jsClassName.begin(), jsClassName.end()); return schema; @@ -393,7 +393,7 @@ struct Array { return List::fromCpp(c); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { return List::schema(); } }; @@ -405,7 +405,7 @@ struct PrimitiveArray { using Boxed = PrimitiveArray; using CppElemType = typename T::CppType; - static CppType toCpp(const ComposerType& v) { + static CppType toCpp(const ComposerType& v) noexcept { auto arr = v.getTypedArrayRef(); const auto* bytes = arr->getBuffer().data(); const auto byteSize = arr->getBuffer().size(); @@ -413,32 +413,32 @@ struct PrimitiveArray { const auto typedSize = byteSize / sizeof(CppElemType); return CppType(typedData, typedData + typedSize); } - static ComposerType fromCpp(const CppType& c) { + static ComposerType fromCpp(const CppType& c) noexcept { auto bytes = Composer::makeShared(); bytes->assignData(reinterpret_cast(c.data()), c.size() * sizeof(CppElemType)); auto arr = Composer::makeShared(U::getArrayType(), bytes); return Composer::Value(arr); } - static const Composer::ValueSchema& schema() { + static const Composer::ValueSchema& schema() noexcept { static auto schema = Composer::ValueSchema::valueTypedArray(); return schema; } }; template <> struct Array : PrimitiveArray { - static Composer::TypedArrayType getArrayType() { + static constexpr Composer::TypedArrayType getArrayType() noexcept { return Composer::TypedArrayType::Int8Array; } }; template <> struct Array : PrimitiveArray { - static Composer::TypedArrayType getArrayType() { + static constexpr Composer::TypedArrayType getArrayType() noexcept { return Composer::TypedArrayType::Int16Array; } }; template <> struct Array : PrimitiveArray { - static Composer::TypedArrayType getArrayType() { + static constexpr Composer::TypedArrayType getArrayType() noexcept { return Composer::TypedArrayType::Int32Array; } }; @@ -448,13 +448,13 @@ struct Array : PrimitiveArray { }; template <> struct Array : PrimitiveArray { - static Composer::TypedArrayType getArrayType() { + static constexpr Composer::TypedArrayType getArrayType() noexcept { return Composer::TypedArrayType::Float32Array; } }; template <> struct Array : PrimitiveArray { - static Composer::TypedArrayType getArrayType() { + static constexpr Composer::TypedArrayType getArrayType() noexcept { return Composer::TypedArrayType::Float64Array; } }; @@ -483,7 +483,7 @@ class ComposerProxyBase { std::lock_guard lk(jsProxyCacheMutex); jsProxyCache.erase(_js->getId()); } - Composer::Ref getProxy() { + Composer::Ref getProxy() noexcept { return _js; } Composer::Value callJsMethod(size_t i, std::initializer_list parameters) { @@ -517,10 +517,10 @@ class DjinniCppProxyObject : public Composer::ValueTypedProxyObject { cppProxyCache.erase(_impl.get()); } } - std::string_view getType() const final { + std::string_view getType() const noexcept final { return "Djinni C++ Proxy"; } - std::shared_ptr getImpl() const { + std::shared_ptr getImpl() const noexcept { return _impl; } @@ -550,14 +550,14 @@ class JsInterface { private: template struct GetOrCreateJsProxy { - std::shared_ptr operator()(const Composer::Value& js) { + std::shared_ptr operator()(const Composer::Value& js) noexcept { assert(false && "Attempting to pass JS object but interface lacks +p"); return {}; } }; template struct GetOrCreateJsProxy> { - std::shared_ptr operator()(const Composer::Value& js) { + std::shared_ptr operator()(const Composer::Value& js) noexcept { auto proxy = js.getTypedProxyObjectRef(); auto obj = proxy->getTypedObject(); std::lock_guard lk(jsProxyCacheMutex); @@ -595,14 +595,14 @@ class JsInterface { // (interface +c) template struct GetOrCreateCppProxy { - Composer::Value operator()(const std::shared_ptr& c) { + Composer::Value operator()(const std::shared_ptr& c) noexcept { assert(false && "Attempting to pass C++ object but interface lacks +c"); return Composer::Value::undefined(); } }; template struct GetOrCreateCppProxy> { - Composer::Value operator()(const std::shared_ptr& c) { + Composer::Value operator()(const std::shared_ptr& c) noexcept { // look up in cpp proxy cache std::lock_guard lk(cppProxyCacheMutex); auto i = cppProxyCache.find(c.get());