Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2020PureCPP

 2020PureCPP

Avatar for LanderlYoung

LanderlYoung

December 26, 2020

Other Decks in Programming

Transcript

  1. 2020 PURE C++大会 JS Java JS JS API WebGL Canvas

    OpenGL ES C++ V8 JSCore Binding Q Ø Ø Ø JS API ScriptEngine
  2. 2020 PURE C++大会 ScriptEngine JavaScript V8 JSCore Lua Lua CPython

    QuickJS WKWebView WebAssembly Python Ruby C# Mono YARV ScriptEngine API C++17 / STL API C++ Android / iOS / MacOS / Windows / Linux / etc. QQ / IEG CrossEngine / PCG 务 / PCG 务 node.js https://git.woa.com/mini_game/ScriptEngine
  3. 2020 PURE C++大会 0 1 2 3 4 5 6

    7 8 add json varargs V8 raw V8 Cocos ReactNative V8pp WX ScriptEngine 0 5 10 15 20 25 30 35 add json varargs JavaScriptCore raw JSCore Cocos ReactNative WX ScriptEngine JS->C++ iMac i9-9900K 32G RAM @macOS 10.15
  4. 2020 PURE C++大会 Number String Array Object Null Function ByteBuffer

    Unsupported Local: Globa: API jsc_interop v8_interop lua_interop
  5. 2020 PURE C++大会 What you don't use, you don't pay

    for. THE DESIGN AND EVOLUTION OF C++ Bjarne Stroustrup
  6. 2020 PURE C++大会 // 辅助 template <typename T> struct ImplType;

    // 声明 template <> class Local<Boolean> { typename ImplType<Local<Boolean>>::type val_; }; // V8实现 template <> struct ImplType<Local<Boolean>> { using type = v8::Local<v8::Boolean>; }; // JSCore实现 template <> struct ImplType<Local<Boolean>> { using type = JSValueRef; };
  7. 2020 PURE C++大会 Inlude if (USE_V8) add_definitions(-DBACKEND_TRAIT_PREFIX=../backend/V8/trait/Trait) elseif (USE_LUA) add_definitions(-DBACKEND_TRAIT_PREFIX=../backend/Lua/trait/Trait)

    endif() CMake配置 #define SCRIPT_ENGINE_BACKEND(FILE) \ MARCO_TO_STRING(MARCO_JOIN(BACKEND_TRAIT_PREFIX, FILE)) 宏拼接 #include SCRIPT_ENGINE_BACKEND(Reference.h) Computed Include #include "../backend/V8/trait/TraitReference.h" 宏展开 Computed include:使用编译期配置的宏参数选择合适的include文件
  8. 2020 PURE C++大会 u C++ u C-99 Variable-length array u

    std::vector u alloca Local<Function>::call(const Local<Value>& thiz, const initializer_list<Local<Value>>& args) v8::Function::Call(…, int argc, v8::Local<v8::Value> argv[])
  9. 2020 PURE C++大会 // template <typename T, size_t N, typename

    FN> void withNArrayCall(FN&& fn) { T array[N]; fn(array); } // 伪 template<typename T, typename FN> void withNArray(size_t size, FN&& fn) { if (size <= 1) { withNArrayCall<T, 1>(forward<FN>(fn)); } else if (size <= 4) { withNArrayCall<T, 4>(forward<FN>(fn)); } else { // fallback to vector } } // 1, 2, 4, 8, 16, 32, 64
  10. 2020 PURE C++大会 f(x) = 2n // size_t f(size_t n)

    { return n == 0 ? 1 : f(n - 1) * 2; }
  11. 2020 PURE C++大会 f(x) = 2n template<size_t N> struct PowOf2

    { static const size_t value = PowOf2<N - 1>::value * 2; }; template<> struct PowOf2<0> { static const size_t value = 1; };
  12. 2020 PURE C++大会 f(x) = 2n // C++ 11 constexpr

    size_t powOf2(size_t n) { return n == 0 ? 1 : powOf2(n - 1) * 2; } [constexpr(since C++11)]
  13. 2020 PURE C++大会 C++ [variadic template(since C++11)] template <typename Func,

    typename... Args> decltype(auto) invoke(Func&& f, Args&&... args) { return f(forward<Args>(args)...); }
  14. 2020 PURE C++大会 C++ template<typename T, typename FN, size_t... I>

    void withNArrayHelper(size_t size, FN&& fn, index_sequence<I...>) { (...|| (size <= powOf2(I) && withNArrayCall<T, powOf2(I), FN>(forward<FN>(fn))) ); } https://cppinsights.io/s/c906f5df [variadic template(since C++11)] [fold expression(since C++17)] withNArrayHelper<T>(size, forward<FN>(fn), make_index_sequence<7>());
  15. 2020 PURE C++大会 RAII+move= ! std::shared_ptr | std::unique_ptr Global<Value> JSValueRef

    Global<Value> JSValueRef JSValueProtect Global<Value> JSValueRef Global<Value> JSValueRef 移动 ScriptEngine API RAII
  16. 2020 PURE C++大会 // 测试 Local<Object> obj; Local<String> key =

    String::newString("name"); obj.get(key); // ok obj.get("name"); // ok obj.get(String::newString("name")); // fail class String { static Local<String> newString(const char* utf8); static Local<String> newString(string_view utf8); static Local<String> newString(const string& utf8); }; class Local<Object> { Local<Value> get(const Local<String>& key) const; template <typename StringLike> // need SFINAE Local<Value> get(StringLike&& key) const { return get(String::newString(forward<StringLike>(key))); } };
  17. 2020 PURE C++大会 Substitution Failure Is Not An Error C++

    TEMPLATES: THE COMPLETE GUIDE David Vandevoorde
  18. 2020 PURE C++大会 SFINAE template <typename T> T add(); template

    <typename T> typename T::value_type add(); add<char>(); // ok add<string>(); // fail template<bool B, class T = void> struct enable_if {}; template<class T> struct enable_if<true, T> { typedef T type; }; template< bool B, class T = void > using enable_if_t = typename enable_if<B,T>::type;
  19. 2020 PURE C++大会 SFINAE // the hard way template <

    typename StringLike, typename T = Local<Value>, typename = enable_if_t<is_convertible_v<StringLike, const char*> || is_convertible_v<StringLike, const string_view&> || is_convertible_v<StringLike, const string&>> > void set(StringLike&& key, T&& value) const; String::newString u String u newString char8_t ?
  20. 2020 PURE C++大会 decltype std::declval std::void_t // the smart way

    template <typename StringLike, typename = std::void_t< decltype(String::newString(std::declval<StringLike>())) > > Local<Value> get(StringLike&& key) const { return get(String::newString(forward<StringLike>(key))); } newString enable u u newString class String { … static Local<String> newString(const char8_t* utf8); static Local<String> newString(u8string_view utf8); static Local<String> newString(u8string& utf8); };
  21. 2020 PURE C++大会 concept -- C++20 // concept -- StringLike

    template<typename T> concept StringLike = requires(T a) { String::newString(a); }; // concept template <StringLike T> Local<Value> get(T&& key) const { return get(String::newString(forward<T>(key))); } https://cppinsights.io/s/5490b1aa
  22. 2020 PURE C++大会 普通C++函数 直接绑定普通C++函数 using FunctionCallback = std::function<Local<Value>(const Arguments&)>;

    Local<Value> add(const Arguments& args) { int a = args[0].asNumber().toInt32(); int b = args[1].asNumber().toInt32(); int ret = real_add(a, b); return Number::newNumber(ret); } int add(int a, int b) { return a + b; } class TestClass : public script::ScriptClass { int age; int add(int a, int b); void setSrc(const string& src); void draw(Image* img); }; defineClass<TestClass>("Test") .constructor() .instanceProperty("age", &TestClass::age) .instanceProperty("src", &TestClass::setSrc) .instanceFunction("add", &TestClass::add) .instanceFunction("draw", &TestClass::draw) .build();
  23. 2020 PURE C++大会 I. Local<Value> add(const Arguments& args) { int

    a = args[0].asNumber().toInt32(); int b = args[1].asNumber().toInt32(); int ret = real_add(a, b); return Number::newNumber(ret); } int add(int a, int b) { return a + b; } 编译期生成 u -> C++ u C++ -> u +
  24. 2020 PURE C++大会 III. template <typename Func, typename Enable =

    void> struct FunctionTrait; template <typename Ret, typename... Args> struct FunctionTrait<Ret (*)(Args...)> { using ReturnType = Ret; using Arguments = tuple<Args...>; }; 1. 普通函数
  25. 2020 PURE C++大会 III. template <typename C, typename Ret, typename...

    Args> struct FunctionTrait<Ret (C::*)(Args...)> : FunctionTrait<Ret (*)(C*, Args...)> {}; 2. const volatile noexcept 7
  26. 2020 PURE C++大会 III. 3. lambda & functor template <typename

    Functor> struct FunctionTrait<Functor, > { using FunctorTrait = FunctionTrait<decltype(&Functor::operator())>; … }; std::void_t<decltype(&Functor::operator())>
  27. 2020 PURE C++大会 III. 4. const & reference & pointer

    // decay: remove const, reference; function type to function pointer template <typename Func> struct FunctionTrait<Func, enable_if_t<!is_same_v<Func, decay_t<Func>>> > : FunctionTrait<decay_t<Func>> {}; template <typename Func> using MyFuncTait = FunctionTrait<decay_t<Func>>; https://cppinsights.io/s/617ff1ea
  28. 2020 PURE C++大会 III. 0. 借用 std::function? template <typename Ret,

    typename... Args> struct FunctionTraitHelper< std::function<Ret(Args...)> > {…}; template <typename Func> struct FunctionTrait : public FunctionTraitHelper< decltype(function(declval<Func>())) > {};
  29. 2020 PURE C++大会 III. std::function a = std::puts; // ok

    std::function b = std::string::c_str; // fail u std::function
  30. 2020 PURE C++大会 IV. template <typename Func> inline FunctionCallback bindFunc(Func&&

    fun) { return [&fun](const Arguments& args) -> Local<Value> { // }; }
  31. 2020 PURE C++大会 IV. template <typename Func, typename... Args, size_t...

    index> inline Local<Value> helper(const Arguments& args, Func& fun, tuple<Args...>*, index_sequence<index...>) { fun(Converter<Args>::toCpp(args[index])...); } using Args = typename FuncTrait<Func>::Arguments; return helper(args, fun, static_cast<Args>(nullptr), std::make_index_sequence<std::tuple_size_v<Args>>());
  32. 2020 PURE C++大会 jsFun.call(); JS C++ obj.get("func"); try { }

    catch (...) { } jsFunc() { throw Error(); } ① ② C++ JS Ø ScriptEngine ① ②
  33. 2020 PURE C++大会 void bridge() void nativeFun() { throw Exception();

    } try { } catch (...) { } nativeFun(); ③ JS C++ JS C++ Ø binding C++ JS ③
  34. 2020 PURE C++大会 C++ JS C++ catch u u u

    script::Exception u u u Google
  35. 2020 PURE C++大会 thread_local newArray f.call() obj.get() 栈 EngineScope ScriptEngine*

    EngineScope::getCurrent() { return current->engine_; } thread_local EngineScope* current; EngineScope::EngineScope() { current->prev_= current; current = this; } ~EngineScope::EngineScope() { current= current->prev_; }