// Copyright 2016 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_WASM_MANAGED_H_ #define V8_WASM_MANAGED_H_ #include "src/factory.h" #include "src/global-handles.h" #include "src/handles.h" #include "src/isolate.h" #include "src/objects-inl.h" namespace v8 { namespace internal { // An object that wraps a pointer to a C++ object and optionally deletes it // when the managed wrapper object is garbage collected. template <class CppType> class Managed : public Foreign { public: V8_INLINE CppType* get() { return reinterpret_cast<CppType*>(foreign_address()); } static Handle<Managed<CppType>> New(Isolate* isolate, CppType* ptr, bool delete_on_gc = true) { Handle<Foreign> foreign = isolate->factory()->NewForeign(reinterpret_cast<Address>(ptr)); Handle<Managed<CppType>> handle( reinterpret_cast<Managed<CppType>*>(*foreign), isolate); if (delete_on_gc) { RegisterWeakCallbackForDelete(isolate, handle); } return handle; } private: static void RegisterWeakCallbackForDelete(Isolate* isolate, Handle<Managed<CppType>> handle) { Handle<Object> global_handle = isolate->global_handles()->Create(*handle); GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(), &Managed<CppType>::Delete, v8::WeakCallbackType::kFinalizer); } static void Delete(const v8::WeakCallbackInfo<void>& data) { Managed<CppType>** p = reinterpret_cast<Managed<CppType>**>(data.GetParameter()); delete (*p)->get(); (*p)->set_foreign_address(0); GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); } }; } // namespace internal } // namespace v8 #endif // V8_WASM_MANAGED_H_