- Handle的分類
- Handle的實現
class Handle {
public:
INLINE(explicit Handle(T** location)) { location_ = location; }
INLINE(explicit Handle(T* obj));
INLINE(Handle(T* obj, Isolate* isolate));
INLINE(Handle()) : location_(NULL) {}
// Constructor for handling automatic up casting.
// Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
template <class S> Handle(Handle<S> handle) {
#ifdef DEBUG
T* a = NULL;
S* b = NULL;
a = b; // Fake assignment to enforce type checks.
USE(a);
#endif
location_ = reinterpret_cast<T**>(handle.location_);
}
INLINE(T* operator ->() const) { return operator*(); }
// Check if this handle refers to the exact same object as the other handle.
INLINE(bool is_identical_to(const Handle<T> other) const);
// Provides the C++ dereference operator.
INLINE(T* operator*() const);
// Returns the address to where the raw pointer is stored.
INLINE(T** location() const);
template <class S> static Handle<T> cast(Handle<S> that) {
T::cast(*that);
return Handle<T>(reinterpret_cast<T**>(that.location()));
}
static Handle<T> null() { return Handle<T>(); }
bool is_null() const { return location_ == NULL; }
// Closes the given scope, but lets this handle escape. See
// implementation in api.h.
inline Handle<T> EscapeFrom(v8::HandleScope* scope);
private:
T** location_;
// Handles of different classes are allowed to access each other's location_.
template<class S> friend class Handle;
};
INLINE(Handle(T* obj, Isolate* isolate));
INLINE(Handle()) : location_(NULL) {}//返回空對象
// After a handle scope has been created, all local handles will be
// allocated within that handle scope until either the handle scope is
// deleted or another handle scope is created. If there is already a
// handle scope and a new one is created, all allocations will take
// place in the new handle scope until it is deleted. After that,
// new handles will again be allocated in the original handle scope.
//
// After the handle scope of a local handle has been deleted the
// garbage collector will no longer track the object stored in the
// handle and may deallocate it. The behavior of accessing a handle
// for which the handle scope has been deleted is undefined.
T** HandleScope::CreateHandle(Isolate* isolate, T* value) {
v8::ImplementationUtilities::HandleScopeData* current =
isolate->handle_scope_data();
internal::Object** cur = current->next;
if (cur == current->limit) cur = Extend(isolate);
// Update the current next field, set the value in the created
// handle, and return the result.
ASSERT(cur < current->limit);
current->next = cur + 1;
//把期望存儲的value值,存儲在T**中
T** result = reinterpret_cast<T**>(cur);
*result = value;
return result;
}
public:
internal::Object** next;
internal::Object** limit;
int level;
V8_INLINE(void Initialize()) {
next = limit = NULL;
level = 0;
}
};
Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
if (that.IsEmpty()) return Local<T>();
T* that_ptr = *that;
internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
reinterpret_cast<internal::Isolate*>(isolate), *p)));
}
Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) {
if (that.IsEmpty()) return Persistent<T>();
internal::Object** p = reinterpret_cast<internal::Object**>(*that);
return Persistent<T>(reinterpret_cast<T*>(
V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
p)));
}
GlobalHandles類中的NodeBlock指針first_used_block_與NodeBlock類中的next_used_和prev_used_指針配合使用,組成了一個雙向鏈表,表示所有正在使用的NodeBlock,即其中存儲有Handle的Block。
- Handle的轉換
v8::internal::Handle<v8::internal::To> Utils::OpenHandle( \
const v8::From* that, bool allow_empty_handle) { \
EXTRA_CHECK(allow_empty_handle || that != NULL); \
EXTRA_CHECK(that == NULL || \
!(*reinterpret_cast<v8::internal::To**>( \
const_cast<v8::From*>(that)))->IsFailure()); \
return v8::internal::Handle<v8::internal::To>( \
reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
}
Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
ASSERT(obj.is_null() || !obj->IsTheHole()); \
return Local<To>(reinterpret_cast<To*>(obj.location())); \
}
v8::Handle<Value> data, v8::Handle<Signature> signature, int length) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
LOG_API(isolate, "FunctionTemplate::New");
ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
i::Handle<i::FunctionTemplateInfo> obj =
i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
InitializeFunctionTemplate(obj);
int next_serial_number = isolate->next_serial_number();
isolate->set_next_serial_number(next_serial_number + 1);
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
if (callback != 0) {
if (data.IsEmpty()) data = v8::Undefined();
Utils::ToLocal(obj)->SetCallHandler(callback, data);
}
obj->set_length(length);
obj->set_undetectable(false);
obj->set_needs_access_check(false);
if (!signature.IsEmpty())
obj->set_signature(*Utils::OpenHandle(*signature));
return Utils::ToLocal(obj);
}