123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // Copyright Joyent, Inc. and other Node contributors.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a
- // copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to permit
- // persons to whom the Software is furnished to do so, subject to the
- // following conditions:
- //
- // The above copyright notice and this permission notice shall be included
- // in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- #ifndef SRC_NODE_OBJECT_WRAP_H_
- #define SRC_NODE_OBJECT_WRAP_H_
-
- #include "v8.h"
- #include <cassert>
-
-
- namespace node {
-
- class ObjectWrap {
- public:
- ObjectWrap() {
- refs_ = 0;
- }
-
-
- virtual ~ObjectWrap() {
- if (persistent().IsEmpty())
- return;
- persistent().ClearWeak();
- persistent().Reset();
- }
-
-
- template <class T>
- static inline T* Unwrap(v8::Local<v8::Object> handle) {
- assert(!handle.IsEmpty());
- assert(handle->InternalFieldCount() > 0);
- // Cast to ObjectWrap before casting to T. A direct cast from void
- // to T won't work right when T has more than one base class.
- void* ptr = handle->GetAlignedPointerFromInternalField(0);
- ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
- return static_cast<T*>(wrap);
- }
-
-
- inline v8::Local<v8::Object> handle() {
- return handle(v8::Isolate::GetCurrent());
- }
-
-
- inline v8::Local<v8::Object> handle(v8::Isolate* isolate) {
- return v8::Local<v8::Object>::New(isolate, persistent());
- }
-
-
- inline v8::Persistent<v8::Object>& persistent() {
- return handle_;
- }
-
-
- protected:
- inline void Wrap(v8::Local<v8::Object> handle) {
- assert(persistent().IsEmpty());
- assert(handle->InternalFieldCount() > 0);
- handle->SetAlignedPointerInInternalField(0, this);
- persistent().Reset(v8::Isolate::GetCurrent(), handle);
- MakeWeak();
- }
-
-
- inline void MakeWeak() {
- persistent().SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
- }
-
- /* Ref() marks the object as being attached to an event loop.
- * Refed objects will not be garbage collected, even if
- * all references are lost.
- */
- virtual void Ref() {
- assert(!persistent().IsEmpty());
- persistent().ClearWeak();
- refs_++;
- }
-
- /* Unref() marks an object as detached from the event loop. This is its
- * default state. When an object with a "weak" reference changes from
- * attached to detached state it will be freed. Be careful not to access
- * the object after making this call as it might be gone!
- * (A "weak reference" means an object that only has a
- * persistent handle.)
- *
- * DO NOT CALL THIS FROM DESTRUCTOR
- */
- virtual void Unref() {
- assert(!persistent().IsEmpty());
- assert(!persistent().IsWeak());
- assert(refs_ > 0);
- if (--refs_ == 0)
- MakeWeak();
- }
-
- int refs_; // ro
-
- private:
- static void WeakCallback(
- const v8::WeakCallbackInfo<ObjectWrap>& data) {
- ObjectWrap* wrap = data.GetParameter();
- assert(wrap->refs_ == 0);
- wrap->handle_.Reset();
- delete wrap;
- }
-
- v8::Persistent<v8::Object> handle_;
- };
-
- } // namespace node
-
- #endif // SRC_NODE_OBJECT_WRAP_H_
|