From bc8973466d3b32fb13e78fd26416cba8d73c602f Mon Sep 17 00:00:00 2001 From: liuweili Date: Tue, 7 Jan 2025 14:18:39 +0800 Subject: [PATCH] add type conversion Signed-off-by: liuweili --- src/type_conversion.h | 169 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/type_conversion.h diff --git a/src/type_conversion.h b/src/type_conversion.h new file mode 100644 index 0000000..10dd3b7 --- /dev/null +++ b/src/type_conversion.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSVM_VALUE_H +#define JSVM_VALUE_H +#include + +#include "jsvm_util.h" + +struct JSVM_Script_Data__ { +public: + using SourcePtr = std::variant, v8::Global>; + using DataType = enum { kJsvmScript }; + + template + JSVM_Script_Data__(T ptr, bool retained, DataType type = kJsvmScript) + : taggedPointer(ptr), isGlobal(retained), type(type) + {} + + template + v8::Local ToV8Local(v8::Isolate* isolate) + { + if (isGlobal) { + return v8::Local::New(isolate, std::get>(taggedPointer)); + } else { + return std::get>(taggedPointer); + } + } + + SourcePtr taggedPointer; + bool isGlobal = false; + DataType type; +}; + +namespace v8impl { +// This asserts v8::Local<> will always be implemented with a single +// pointer field so that we can pass it around as a void*. +static_assert(sizeof(v8::Local) == sizeof(JSVM_Data), + "Cannot convert between v8::Local and JSVM_Data"); + +inline JSVM_Data JsDataFromV8LocalData(v8::Local local) +{ + return reinterpret_cast(*local); +} + +inline v8::Local V8LocalDataFromJsData(JSVM_Data data) +{ + v8::Local local; + *reinterpret_cast(&local) = data; + return local; +} + +// This asserts v8::Local<> will always be implemented with a single +// pointer field so that we can pass it around as a void*. +static_assert(sizeof(v8::Local) == sizeof(JSVM_Value), + "Cannot convert between v8::Local and JSVM_Value"); + +inline JSVM_Value JsValueFromV8LocalValue(v8::Local local) +{ + return reinterpret_cast(*local); +} + +inline v8::Local V8LocalValueFromJsValue(JSVM_Value value) +{ + v8::Local local; + *reinterpret_cast(&local) = value; + return local; +} + +inline JSVM_Deferred JsDeferredFromPersistent(v8impl::Persistent* local) +{ + return reinterpret_cast(local); +} + +inline v8impl::Persistent* PersistentFromJsDeferred(JSVM_Deferred local) +{ + return reinterpret_cast*>(local); +} + +class HandleScopeWrapper { +public: + explicit HandleScopeWrapper(v8::Isolate* isolate) : scope(isolate) {} + +private: + v8::HandleScope scope; +}; + +class EscapableHandleScopeWrapper { +public: + explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) : scope(isolate), escapeCalled(false) {} + bool IsEscapeCalled() const + { + return escapeCalled; + } + template + v8::Local Escape(v8::Local handle) + { + escapeCalled = true; + return scope.Escape(handle); + } + +private: + v8::EscapableHandleScope scope; + bool escapeCalled; +}; + +inline JSVM_HandleScope JsHandleScopeFromV8HandleScope(HandleScopeWrapper* s) +{ + return reinterpret_cast(s); +} + +inline HandleScopeWrapper* V8HandleScopeFromJsHandleScope(JSVM_HandleScope s) +{ + return reinterpret_cast(s); +} + +inline JSVM_EscapableHandleScope JsEscapableHandleScopeFromV8EscapableHandleScope(EscapableHandleScopeWrapper* s) +{ + return reinterpret_cast(s); +} + +inline EscapableHandleScopeWrapper* V8EscapableHandleScopeFromJsEscapableHandleScope(JSVM_EscapableHandleScope s) +{ + return reinterpret_cast(s); +} + +// Convert a v8::PersistentBase, e.g. v8::Global, to a Local, with an extra +// optimization for strong persistent handles. +class PersistentToLocal { +public: + // Convert v8::Global to v8::Local + template + static inline v8::Local Default(v8::Isolate* isolate, const v8::PersistentBase& persistent) + { + if (persistent.IsWeak()) { + return PersistentToLocal::Weak(isolate, persistent); + } else { + return PersistentToLocal::Strong(persistent); + } + } + + template + static inline v8::Local Strong(const v8::PersistentBase& persistent) + { + DCHECK(!persistent.IsWeak()); + return *reinterpret_cast*>(const_cast*>(&persistent)); + } + + template + static inline v8::Local Weak(v8::Isolate* isolate, const v8::PersistentBase& persistent) + { + return v8::Local::New(isolate, persistent); + } +}; +} // namespace v8impl + +#endif \ No newline at end of file -- Gitee