| // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| /* | |
| Generated with: | |
| dart pkg/vm/tool/generate_entry_point_shims.dart \ | |
| out/ReleaseX64/gen/samples/embedder/timer_aot.dart.dill \ | |
| samples/embedder/timer | |
| */ | |
| #include "timer.h" | |
| #include <iostream> | |
| #include <string> | |
| #include <string_view> | |
| #include <unordered_map> | |
| #include <vector> | |
| namespace { | |
| Dart_Handle CheckError(Dart_Handle handle, std::string_view context = "") { | |
| if (Dart_IsError(handle)) { | |
| std::cerr << "Error " << context << ": " << Dart_GetError(handle) | |
| << std::endl; | |
| std::exit(1); | |
| } | |
| return handle; | |
| } | |
| int64_t IntFromHandle(Dart_Handle handle) { | |
| CheckError(handle, "IntFromHandle received an error"); | |
| if (!Dart_IsInteger(handle)) { | |
| std::cerr << "IntFromHandle handle is not an int" << std::endl; | |
| std::exit(1); | |
| } | |
| int64_t result; | |
| Dart_Handle to_int64_result = Dart_IntegerToInt64(handle, &result); | |
| CheckError(to_int64_result, "Dart_IntegerToInt64"); | |
| return result; | |
| } | |
| double DoubleFromHandle(Dart_Handle handle) { | |
| CheckError(handle, "DoubleFromHandle received an error"); | |
| if (!Dart_IsDouble(handle)) { | |
| std::cerr << "DoubleFromHandle handle is not an double" << std::endl; | |
| std::exit(1); | |
| } | |
| double result; | |
| Dart_Handle to_double_result = Dart_DoubleValue(handle, &result); | |
| CheckError(to_double_result, "Dart_DoubleValue"); | |
| return result; | |
| } | |
| class PackageState { | |
| public: | |
| static PackageState* instance() { | |
| static PackageState* instance = new PackageState(); | |
| return instance; | |
| } | |
| Dart_Handle PackageLibrary() { | |
| ValidateCurrentIsolate(); | |
| Dart_Handle result = package_library_; | |
| if (package_library_ == nullptr) { | |
| result = Dart_RootLibrary(); | |
| if (!Dart_IsError(result)) { | |
| package_library_ = Dart_NewPersistentHandle(result); | |
| } | |
| } | |
| return result; | |
| } | |
| Dart_Handle TypeWithDefaults(std::string name) { | |
| ValidateCurrentIsolate(); | |
| auto search = default_types_.find(name); | |
| Dart_Handle result; | |
| if (search == default_types_.end()) { | |
| Dart_Handle lib = PackageLibrary(); | |
| result = Dart_GetClass(lib, Dart_NewStringFromCString(name.c_str())); | |
| if (!Dart_IsError(result)) { | |
| Dart_PersistentHandle handle = Dart_NewPersistentHandle(result); | |
| default_types_.emplace(std::make_pair(name, handle)); | |
| } | |
| } else { | |
| result = search->second; | |
| } | |
| return result; | |
| } | |
| private: | |
| PackageState() : default_types_() {} | |
| void ValidateCurrentIsolate() { | |
| Dart_Isolate current = Dart_CurrentIsolate(); | |
| if (isolate_ != current) { | |
| isolate_ = current; | |
| if (package_library_ != nullptr) { | |
| Dart_DeletePersistentHandle(package_library_); | |
| package_library_ = nullptr; | |
| } | |
| for (const auto& [str, handle] : default_types_) { | |
| Dart_DeletePersistentHandle(handle); | |
| } | |
| default_types_.clear(); | |
| } | |
| } | |
| // Ensure the helper methods defined above won't trigger unused | |
| // function warnings. | |
| template <typename T> | |
| static inline void USE(T&&) {} | |
| void UseHelperFunctions() { | |
| USE(IntFromHandle); | |
| USE(DoubleFromHandle); | |
| } | |
| Dart_Isolate isolate_ = nullptr; | |
| Dart_PersistentHandle package_library_ = nullptr; | |
| std::unordered_map<std::string, Dart_PersistentHandle> default_types_; | |
| }; | |
| class DartScope { | |
| public: | |
| DartScope() { Dart_EnterScope(); } | |
| virtual ~DartScope() { Dart_ExitScope(); } | |
| private: | |
| DartScope(const DartScope&) = delete; | |
| void operator=(const DartScope&) = delete; | |
| }; | |
| class IsolateScope { | |
| public: | |
| explicit IsolateScope(Dart_Isolate isolate) { | |
| DartEngine_AcquireIsolate(isolate); | |
| } | |
| virtual ~IsolateScope() { DartEngine_ReleaseIsolate(); } | |
| private: | |
| IsolateScope(const IsolateScope&) = delete; | |
| void operator=(const IsolateScope&) = delete; | |
| }; | |
| } // namespace | |
| #ifdef __cplusplus | |
| #define PACKAGE_EXTERN_C extern "C" | |
| #else | |
| #define PACKAGE_EXTERN_C extern | |
| #endif | |
| #if defined(__CYGWIN__) | |
| #error Tool chain and platform not supported. | |
| #elif defined(_WIN32) | |
| #define PACKAGE_EXPORT PACKAGE_EXTERN_C __declspec(dllexport) | |
| #else | |
| #if __GNUC__ >= 4 | |
| #define PACKAGE_EXPORT \ | |
| PACKAGE_EXTERN_C __attribute__((visibility("default"))) __attribute((used)) | |
| #else | |
| #error Tool chain not supported. | |
| #endif | |
| #endif | |
| PACKAGE_EXPORT void Call_startTimer(Dart_Isolate dart_isolate, | |
| int64_t v_millis) { | |
| IsolateScope isolate_scope(dart_isolate); | |
| DartScope scope; | |
| std::vector parameter_list{Dart_NewInteger(v_millis)}; | |
| CheckError(Dart_Invoke(PackageState::instance()->PackageLibrary(), | |
| Dart_NewStringFromCString("startTimer"), 1, | |
| parameter_list.data())); | |
| } | |
| PACKAGE_EXPORT void Call_stopTimer(Dart_Isolate dart_isolate) { | |
| IsolateScope isolate_scope(dart_isolate); | |
| DartScope scope; | |
| CheckError(Dart_Invoke(PackageState::instance()->PackageLibrary(), | |
| Dart_NewStringFromCString("stopTimer"), 0, nullptr)); | |
| } | |
| PACKAGE_EXPORT void Call_resetTimer(Dart_Isolate dart_isolate) { | |
| IsolateScope isolate_scope(dart_isolate); | |
| DartScope scope; | |
| CheckError(Dart_Invoke(PackageState::instance()->PackageLibrary(), | |
| Dart_NewStringFromCString("resetTimer"), 0, nullptr)); | |
| } | |
| PACKAGE_EXPORT int64_t Get_ticks(Dart_Isolate dart_isolate) { | |
| IsolateScope isolate_scope(dart_isolate); | |
| DartScope scope; | |
| return IntFromHandle(Dart_GetField(PackageState::instance()->PackageLibrary(), | |
| Dart_NewStringFromCString("ticks"))); | |
| } | |
| #undef PACKAGE_EXPORT | |
| #undef PACKAGE_EXTERN_C |