1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_WASM_MANAGED_H_
6 #define V8_WASM_MANAGED_H_
7 
8 #include "src/factory.h"
9 #include "src/global-handles.h"
10 #include "src/handles.h"
11 #include "src/isolate.h"
12 #include "src/objects-inl.h"
13 
14 namespace v8 {
15 namespace internal {
16 // An object that wraps a pointer to a C++ object and optionally deletes it
17 // when the managed wrapper object is garbage collected.
18 template <class CppType>
19 class Managed : public Foreign {
20  public:
get()21   V8_INLINE CppType* get() {
22     return reinterpret_cast<CppType*>(foreign_address());
23   }
24 
25   static Handle<Managed<CppType>> New(Isolate* isolate, CppType* ptr,
26                                       bool delete_on_gc = true) {
27     Handle<Foreign> foreign =
28         isolate->factory()->NewForeign(reinterpret_cast<Address>(ptr));
29     Handle<Managed<CppType>> handle(
30         reinterpret_cast<Managed<CppType>*>(*foreign), isolate);
31     if (delete_on_gc) {
32       RegisterWeakCallbackForDelete(isolate, handle);
33     }
34     return handle;
35   }
36 
37  private:
RegisterWeakCallbackForDelete(Isolate * isolate,Handle<Managed<CppType>> handle)38   static void RegisterWeakCallbackForDelete(Isolate* isolate,
39                                             Handle<Managed<CppType>> handle) {
40     Handle<Object> global_handle = isolate->global_handles()->Create(*handle);
41     GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
42                             &Managed<CppType>::Delete,
43                             v8::WeakCallbackType::kFinalizer);
44   }
Delete(const v8::WeakCallbackInfo<void> & data)45   static void Delete(const v8::WeakCallbackInfo<void>& data) {
46     Managed<CppType>** p =
47         reinterpret_cast<Managed<CppType>**>(data.GetParameter());
48     delete (*p)->get();
49     (*p)->set_foreign_address(0);
50     GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
51   }
52 };
53 }  // namespace internal
54 }  // namespace v8
55 
56 #endif  // V8_WASM_MANAGED_H_
57