Home | History | Annotate | Download | only in src
      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 
     13 namespace v8 {
     14 namespace internal {
     15 // An object that wraps a pointer to a C++ object and manages its lifetime.
     16 // The C++ object will be deleted when the managed wrapper object is
     17 // garbage collected, or, last resort, if the isolate is torn down before GC,
     18 // as part of Isolate::Dispose().
     19 // Managed<CppType> may be used polymorphically as Foreign, where the held
     20 // address is typed as CppType**. The double indirection is due to the
     21 // use, by Managed, of Isolate::ManagedObjectFinalizer, which has a CppType*
     22 // first field.
     23 template <class CppType>
     24 class Managed : public Foreign {
     25  public:
     26   V8_INLINE CppType* get() {
     27     return *(reinterpret_cast<CppType**>(foreign_address()));
     28   }
     29 
     30   static Managed<CppType>* cast(Object* obj) {
     31     SLOW_DCHECK(obj->IsForeign());
     32     return reinterpret_cast<Managed<CppType>*>(obj);
     33   }
     34 
     35   static Handle<Managed<CppType>> New(Isolate* isolate, CppType* ptr) {
     36     Isolate::ManagedObjectFinalizer* node =
     37         isolate->RegisterForReleaseAtTeardown(ptr,
     38                                               Managed<CppType>::NativeDelete);
     39     Handle<Managed<CppType>> handle = Handle<Managed<CppType>>::cast(
     40         isolate->factory()->NewForeign(reinterpret_cast<Address>(node)));
     41     RegisterWeakCallbackForDelete(isolate, handle);
     42     return handle;
     43   }
     44 
     45  private:
     46   static void RegisterWeakCallbackForDelete(Isolate* isolate,
     47                                             Handle<Managed<CppType>> handle) {
     48     Handle<Object> global_handle = isolate->global_handles()->Create(*handle);
     49     GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
     50                             &Managed<CppType>::GCDelete,
     51                             v8::WeakCallbackType::kFinalizer);
     52   }
     53 
     54   static void GCDelete(const v8::WeakCallbackInfo<void>& data) {
     55     Managed<CppType>** p =
     56         reinterpret_cast<Managed<CppType>**>(data.GetParameter());
     57 
     58     Isolate::ManagedObjectFinalizer* finalizer = (*p)->GetFinalizer();
     59 
     60     Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
     61     finalizer->Dispose();
     62     isolate->UnregisterFromReleaseAtTeardown(&finalizer);
     63 
     64     (*p)->set_foreign_address(static_cast<Address>(nullptr));
     65     GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
     66   }
     67 
     68   static void NativeDelete(void* value) {
     69     CppType* typed_value = reinterpret_cast<CppType*>(value);
     70     delete typed_value;
     71   }
     72 
     73   Isolate::ManagedObjectFinalizer* GetFinalizer() {
     74     return reinterpret_cast<Isolate::ManagedObjectFinalizer*>(
     75         foreign_address());
     76   }
     77 };
     78 }  // namespace internal
     79 }  // namespace v8
     80 
     81 #endif  // V8_WASM_MANAGED_H_
     82