Browse Source

src: remove ObjectWrap dependency from core

Drop the ObjectWrap dependency in favor of an internal WeakObject class.

Let's us stop worrying about API and ABI compatibility when making
changes to the way node.js deals with weakly persistent handles
internally.
v0.11.8-release
Ben Noordhuis 11 years ago
parent
commit
c79d5163e5
  1. 2
      node.gyp
  2. 15
      src/node_contextify.cc
  3. 135
      src/node_crypto.cc
  4. 62
      src/node_crypto.h
  5. 27
      src/node_http_parser.cc
  6. 21
      src/node_stat_watcher.cc
  7. 5
      src/node_stat_watcher.h
  8. 34
      src/node_zlib.cc
  9. 18
      src/tls_wrap.cc
  10. 8
      src/tls_wrap.h
  11. 71
      src/weak-object-inl.h
  12. 54
      src/weak-object.h

2
node.gyp

@ -144,6 +144,8 @@
'src/tree.h', 'src/tree.h',
'src/util.h', 'src/util.h',
'src/util-inl.h', 'src/util-inl.h',
'src/weak-object.h',
'src/weak-object-inl.h',
'deps/http_parser/http_parser.h', 'deps/http_parser/http_parser.h',
'<(SHARED_INTERMEDIATE_DIR)/node_natives.h', '<(SHARED_INTERMEDIATE_DIR)/node_natives.h',
# javascript files to make for an even more pleasant IDE experience # javascript files to make for an even more pleasant IDE experience

15
src/node_contextify.cc

@ -24,6 +24,8 @@
#include "node_watchdog.h" #include "node_watchdog.h"
#include "env.h" #include "env.h"
#include "env-inl.h" #include "env-inl.h"
#include "weak-object.h"
#include "weak-object-inl.h"
namespace node { namespace node {
@ -304,7 +306,7 @@ class ContextifyContext {
} }
}; };
class ContextifyScript : public ObjectWrap { class ContextifyScript : public WeakObject {
private: private:
Persistent<Script> script_; Persistent<Script> script_;
@ -335,8 +337,8 @@ class ContextifyScript : public ObjectWrap {
return ThrowError("Must call vm.Script as a constructor."); return ThrowError("Must call vm.Script as a constructor.");
} }
ContextifyScript *contextify_script = new ContextifyScript(); ContextifyScript* contextify_script =
contextify_script->Wrap(args.Holder()); new ContextifyScript(args.GetIsolate(), args.This());
TryCatch try_catch; TryCatch try_catch;
Local<String> code = args[0]->ToString(); Local<String> code = args[0]->ToString();
@ -497,7 +499,7 @@ class ContextifyScript : public ObjectWrap {
} }
ContextifyScript* wrapped_script = ContextifyScript* wrapped_script =
ObjectWrap::Unwrap<ContextifyScript>(args.This()); WeakObject::Unwrap<ContextifyScript>(args.This());
Local<Script> script = PersistentToLocal(node_isolate, Local<Script> script = PersistentToLocal(node_isolate,
wrapped_script->script_); wrapped_script->script_);
@ -527,6 +529,11 @@ class ContextifyScript : public ObjectWrap {
} }
ContextifyScript(Isolate* isolate, Local<Object> object)
: WeakObject(isolate, object) {
}
~ContextifyScript() { ~ContextifyScript() {
script_.Dispose(); script_.Dispose();
} }

135
src/node_crypto.cc

@ -223,16 +223,14 @@ void SecureContext::Initialize(Environment* env, Handle<Object> target) {
void SecureContext::New(const FunctionCallbackInfo<Value>& args) { void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope handle_scope(args.GetIsolate()); new SecureContext(env, args.This());
SecureContext* sc = new SecureContext(env);
sc->Wrap(args.This());
} }
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) { void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
OPENSSL_CONST SSL_METHOD *method = SSLv23_method(); OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
@ -356,7 +354,7 @@ static X509* LoadX509(Handle<Value> v) {
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) { void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
unsigned int len = args.Length(); unsigned int len = args.Length();
if (len != 1 && len != 2) { if (len != 1 && len != 2) {
@ -458,7 +456,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) { void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1) { if (args.Length() != 1) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -485,7 +483,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
bool newCAStore = false; bool newCAStore = false;
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1) { if (args.Length() != 1) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -513,7 +511,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) { void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1) { if (args.Length() != 1) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -544,7 +542,7 @@ void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) { void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
assert(sc->ca_store_ == NULL); assert(sc->ca_store_ == NULL);
@ -581,7 +579,7 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) { void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1 || !args[0]->IsString()) { if (args.Length() != 1 || !args[0]->IsString()) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -595,7 +593,7 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) { void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1 || !args[0]->IntegerValue()) { if (args.Length() != 1 || !args[0]->IntegerValue()) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -609,7 +607,7 @@ void SecureContext::SetSessionIdContext(
const FunctionCallbackInfo<Value>& args) { const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1 || !args[0]->IsString()) { if (args.Length() != 1 || !args[0]->IsString()) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -645,7 +643,7 @@ void SecureContext::SetSessionIdContext(
void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) { void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() != 1 || !args[0]->IsInt32()) { if (args.Length() != 1 || !args[0]->IsInt32()) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -658,7 +656,7 @@ void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
void SecureContext::Close(const FunctionCallbackInfo<Value>& args) { void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
sc->FreeCTXMem(); sc->FreeCTXMem();
} }
@ -675,7 +673,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
char* pass = NULL; char* pass = NULL;
bool ret = false; bool ret = false;
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args.This());
if (args.Length() < 1) { if (args.Length() < 1) {
return ThrowTypeError("Bad parameter"); return ThrowTypeError("Bad parameter");
@ -846,7 +844,7 @@ int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
sess->session_id_length); sess->session_id_length);
Local<Value> argv[] = { session, buff }; Local<Value> argv[] = { session, buff };
MakeCallback(env, MakeCallback(env,
w->handle(node_isolate), w->weak_object(node_isolate),
env->onnewsession_string(), env->onnewsession_string(),
ARRAY_SIZE(argv), ARRAY_SIZE(argv),
argv); argv);
@ -881,7 +879,7 @@ void SSLWrap<Base>::OnClientHello(void* arg,
Local<Value> argv[] = { hello_obj }; Local<Value> argv[] = { hello_obj };
MakeCallback(env, MakeCallback(env,
w->handle(node_isolate), w->weak_object(node_isolate),
env->onclienthello_string(), env->onclienthello_string(),
ARRAY_SIZE(argv), ARRAY_SIZE(argv),
argv); argv);
@ -1423,7 +1421,7 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Local<Value> exception = Local<Value> exception =
Exception::Error(OneByteString(node_isolate, ssl_error_buf)); Exception::Error(OneByteString(node_isolate, ssl_error_buf));
handle(node_isolate)->Set( weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception); FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
@ -1467,7 +1465,7 @@ int Connection::HandleSSLError(const char* func,
} else if (err == SSL_ERROR_ZERO_RETURN) { } else if (err == SSL_ERROR_ZERO_RETURN) {
Local<Value> exception = Local<Value> exception =
Exception::Error(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN")); Exception::Error(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN"));
handle(node_isolate)->Set( weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception); FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
return rv; return rv;
@ -1492,7 +1490,7 @@ int Connection::HandleSSLError(const char* func,
BIO_get_mem_ptr(bio, &mem); BIO_get_mem_ptr(bio, &mem);
Local<Value> exception = Local<Value> exception =
Exception::Error(OneByteString(node_isolate, mem->data, mem->length)); Exception::Error(OneByteString(node_isolate, mem->data, mem->length));
handle(node_isolate)->Set( weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception); FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
BIO_free_all(bio); BIO_free_all(bio);
} }
@ -1510,7 +1508,7 @@ void Connection::ClearError() {
// We should clear the error in JS-land // We should clear the error in JS-land
Local<String> error_key = FIXED_ONE_BYTE_STRING(node_isolate, "error"); Local<String> error_key = FIXED_ONE_BYTE_STRING(node_isolate, "error");
Local<Value> error = handle(node_isolate)->Get(error_key); Local<Value> error = weak_object(node_isolate)->Get(error_key);
assert(error->BooleanValue() == false); assert(error->BooleanValue() == false);
#endif // NDEBUG #endif // NDEBUG
} }
@ -1524,13 +1522,13 @@ void Connection::SetShutdownFlags() {
if (flags & SSL_SENT_SHUTDOWN) { if (flags & SSL_SENT_SHUTDOWN) {
Local<String> sent_shutdown_key = Local<String> sent_shutdown_key =
FIXED_ONE_BYTE_STRING(node_isolate, "sentShutdown"); FIXED_ONE_BYTE_STRING(node_isolate, "sentShutdown");
handle(node_isolate)->Set(sent_shutdown_key, True(node_isolate)); weak_object(node_isolate)->Set(sent_shutdown_key, True(node_isolate));
} }
if (flags & SSL_RECEIVED_SHUTDOWN) { if (flags & SSL_RECEIVED_SHUTDOWN) {
Local<String> received_shutdown_key = Local<String> received_shutdown_key =
FIXED_ONE_BYTE_STRING(node_isolate, "receivedShutdown"); FIXED_ONE_BYTE_STRING(node_isolate, "receivedShutdown");
handle(node_isolate)->Set(received_shutdown_key, True(node_isolate)); weak_object(node_isolate)->Set(received_shutdown_key, True(node_isolate));
} }
} }
@ -1645,7 +1643,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
env->secure_context_constructor_template(); env->secure_context_constructor_template();
if (secure_context_constructor_template->HasInstance(ret)) { if (secure_context_constructor_template->HasInstance(ret)) {
conn->sniContext_.Reset(node_isolate, ret); conn->sniContext_.Reset(node_isolate, ret);
SecureContext* sc = ObjectWrap::Unwrap<SecureContext>(ret.As<Object>()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(ret.As<Object>());
SSL_set_SSL_CTX(s, sc->ctx_); SSL_set_SSL_CTX(s, sc->ctx_);
} else { } else {
return SSL_TLSEXT_ERR_NOACK; return SSL_TLSEXT_ERR_NOACK;
@ -1664,16 +1662,14 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
return ThrowError("First argument must be a crypto module Credentials"); return ThrowError("First argument must be a crypto module Credentials");
} }
SecureContext* sc = ObjectWrap::Unwrap<SecureContext>(args[0]->ToObject()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(args[0]->ToObject());
Environment* env = sc->env(); Environment* env = sc->env();
bool is_server = args[1]->BooleanValue(); bool is_server = args[1]->BooleanValue();
SSLWrap<Connection>::Kind kind = SSLWrap<Connection>::Kind kind =
is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient; is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
Connection* conn = new Connection(env, sc, kind); Connection* conn = new Connection(env, args.This(), sc, kind);
conn->Wrap(args.This());
conn->ssl_ = SSL_new(sc->ctx_); conn->ssl_ = SSL_new(sc->ctx_);
conn->bio_read_ = NodeBIO::New(); conn->bio_read_ = NodeBIO::New();
conn->bio_write_ = NodeBIO::New(); conn->bio_write_ = NodeBIO::New();
@ -1759,13 +1755,13 @@ void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
if (where & SSL_CB_HANDSHAKE_START) { if (where & SSL_CB_HANDSHAKE_START) {
MakeCallback(env, MakeCallback(env,
conn->handle(node_isolate), conn->weak_object(node_isolate),
env->onhandshakestart_string()); env->onhandshakestart_string());
} }
if (where & SSL_CB_HANDSHAKE_DONE) { if (where & SSL_CB_HANDSHAKE_DONE) {
MakeCallback(env, MakeCallback(env,
conn->handle(node_isolate), conn->weak_object(node_isolate),
env->onhandshakedone_string()); env->onhandshakedone_string());
} }
} }
@ -2079,9 +2075,8 @@ void CipherBase::Initialize(Environment* env, Handle<Object> target) {
void CipherBase::New(const FunctionCallbackInfo<Value>& args) { void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall() == true); assert(args.IsConstructCall() == true);
HandleScope scope(node_isolate); CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
CipherBase* cipher = new CipherBase(args[0]->IsTrue() ? kCipher : kDecipher); new CipherBase(args.GetIsolate(), args.This(), kind);
cipher->Wrap(args.This());
} }
@ -2128,7 +2123,7 @@ void CipherBase::Init(const char* cipher_type,
void CipherBase::Init(const FunctionCallbackInfo<Value>& args) { void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); CipherBase* cipher = WeakObject::Unwrap<CipherBase>(args.This());
if (args.Length() < 2 || if (args.Length() < 2 ||
!(args[0]->IsString() && Buffer::HasInstance(args[1]))) { !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
@ -2180,7 +2175,7 @@ void CipherBase::InitIv(const char* cipher_type,
void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) { void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); CipherBase* cipher = WeakObject::Unwrap<CipherBase>(args.This());
if (args.Length() < 3 || !args[0]->IsString()) { if (args.Length() < 3 || !args[0]->IsString()) {
return ThrowError("Must give cipher-type, key, and iv as argument"); return ThrowError("Must give cipher-type, key, and iv as argument");
@ -2217,7 +2212,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope handle_scope(args.GetIsolate()); HandleScope handle_scope(args.GetIsolate());
CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); CipherBase* cipher = WeakObject::Unwrap<CipherBase>(args.This());
ASSERT_IS_STRING_OR_BUFFER(args[0]); ASSERT_IS_STRING_OR_BUFFER(args[0]);
@ -2262,7 +2257,7 @@ bool CipherBase::SetAutoPadding(bool auto_padding) {
void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) { void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); CipherBase* cipher = WeakObject::Unwrap<CipherBase>(args.This());
cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue()); cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
} }
@ -2283,7 +2278,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope handle_scope(args.GetIsolate()); HandleScope handle_scope(args.GetIsolate());
CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); CipherBase* cipher = WeakObject::Unwrap<CipherBase>(args.This());
unsigned char* out_value = NULL; unsigned char* out_value = NULL;
int out_len = -1; int out_len = -1;
@ -2317,9 +2312,7 @@ void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Hmac::New(const FunctionCallbackInfo<Value>& args) { void Hmac::New(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); new Hmac(args.GetIsolate(), args.This());
Hmac* hmac = new Hmac();
hmac->Wrap(args.This());
} }
@ -2344,7 +2337,7 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) { void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); Hmac* hmac = WeakObject::Unwrap<Hmac>(args.This());
if (args.Length() < 2 || !args[0]->IsString()) { if (args.Length() < 2 || !args[0]->IsString()) {
return ThrowError("Must give hashtype string, key as arguments"); return ThrowError("Must give hashtype string, key as arguments");
@ -2369,7 +2362,7 @@ bool Hmac::HmacUpdate(const char* data, int len) {
void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) { void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); Hmac* hmac = WeakObject::Unwrap<Hmac>(args.This());
ASSERT_IS_STRING_OR_BUFFER(args[0]); ASSERT_IS_STRING_OR_BUFFER(args[0]);
@ -2410,7 +2403,7 @@ bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) { void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); Hmac* hmac = WeakObject::Unwrap<Hmac>(args.This());
enum encoding encoding = BUFFER; enum encoding encoding = BUFFER;
if (args.Length() >= 1) { if (args.Length() >= 1) {
@ -2454,13 +2447,10 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
const String::Utf8Value hash_type(args[0]); const String::Utf8Value hash_type(args[0]);
Hash* hash = new Hash(); Hash* hash = new Hash(args.GetIsolate(), args.This());
if (!hash->HashInit(*hash_type)) { if (!hash->HashInit(*hash_type)) {
delete hash;
return ThrowError("Digest method not supported"); return ThrowError("Digest method not supported");
} }
hash->Wrap(args.This());
} }
@ -2485,7 +2475,7 @@ bool Hash::HashUpdate(const char* data, int len) {
void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) { void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Hash* hash = ObjectWrap::Unwrap<Hash>(args.This()); Hash* hash = WeakObject::Unwrap<Hash>(args.This());
ASSERT_IS_STRING_OR_BUFFER(args[0]); ASSERT_IS_STRING_OR_BUFFER(args[0]);
@ -2516,7 +2506,7 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) { void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Hash* hash = ObjectWrap::Unwrap<Hash>(args.This()); Hash* hash = WeakObject::Unwrap<Hash>(args.This());
if (!hash->initialised_) { if (!hash->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -2554,9 +2544,7 @@ void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Sign::New(const FunctionCallbackInfo<Value>& args) { void Sign::New(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); new Sign(args.GetIsolate(), args.This());
Sign* sign = new Sign();
sign->Wrap(args.This());
} }
@ -2577,7 +2565,7 @@ void Sign::SignInit(const char* sign_type) {
void Sign::SignInit(const FunctionCallbackInfo<Value>& args) { void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); Sign* sign = WeakObject::Unwrap<Sign>(args.This());
if (args.Length() == 0 || !args[0]->IsString()) { if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowError("Must give signtype string as argument"); return ThrowError("Must give signtype string as argument");
@ -2598,7 +2586,7 @@ bool Sign::SignUpdate(const char* data, int len) {
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) { void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); Sign* sign = WeakObject::Unwrap<Sign>(args.This());
ASSERT_IS_STRING_OR_BUFFER(args[0]); ASSERT_IS_STRING_OR_BUFFER(args[0]);
@ -2652,7 +2640,7 @@ bool Sign::SignFinal(unsigned char** md_value,
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) { void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); Sign* sign = WeakObject::Unwrap<Sign>(args.This());
unsigned char* md_value; unsigned char* md_value;
unsigned int md_len; unsigned int md_len;
@ -2697,9 +2685,7 @@ void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Verify::New(const FunctionCallbackInfo<Value>& args) { void Verify::New(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); new Verify(args.GetIsolate(), args.This());
Verify* verify = new Verify();
verify->Wrap(args.This());
} }
@ -2721,7 +2707,7 @@ void Verify::VerifyInit(const char* verify_type) {
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) { void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); Verify* verify = WeakObject::Unwrap<Verify>(args.This());
if (args.Length() == 0 || !args[0]->IsString()) { if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowError("Must give verifytype string as argument"); return ThrowError("Must give verifytype string as argument");
@ -2742,7 +2728,7 @@ bool Verify::VerifyUpdate(const char* data, int len) {
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) { void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); Verify* verify = WeakObject::Unwrap<Verify>(args.This());
ASSERT_IS_STRING_OR_BUFFER(args[0]); ASSERT_IS_STRING_OR_BUFFER(args[0]);
@ -2851,7 +2837,7 @@ bool Verify::VerifyFinal(const char* key_pem,
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) { void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); Verify* verify = WeakObject::Unwrap<Verify>(args.This());
ASSERT_IS_BUFFER(args[0]); ASSERT_IS_BUFFER(args[0]);
char* kbuf = Buffer::Data(args[0]); char* kbuf = Buffer::Data(args[0]);
@ -2951,7 +2937,8 @@ void DiffieHellman::DiffieHellmanGroup(
const FunctionCallbackInfo<Value>& args) { const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = new DiffieHellman(); DiffieHellman* diffieHellman =
new DiffieHellman(args.GetIsolate(), args.This());
if (args.Length() != 1 || !args[0]->IsString()) { if (args.Length() != 1 || !args[0]->IsString()) {
return ThrowError("No group name given"); return ThrowError("No group name given");
@ -2968,7 +2955,6 @@ void DiffieHellman::DiffieHellmanGroup(
it->prime_size, it->prime_size,
it->gen, it->gen,
it->gen_size); it->gen_size);
diffieHellman->Wrap(args.This());
return; return;
} }
@ -2979,7 +2965,8 @@ void DiffieHellman::DiffieHellmanGroup(
void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) { void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = new DiffieHellman(); DiffieHellman* diffieHellman =
new DiffieHellman(args.GetIsolate(), args.This());
bool initialized = false; bool initialized = false;
if (args.Length() > 0) { if (args.Length() > 0) {
@ -2994,8 +2981,6 @@ void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
if (!initialized) { if (!initialized) {
return ThrowError("Initialization failed"); return ThrowError("Initialization failed");
} }
diffieHellman->Wrap(args.This());
} }
@ -3003,7 +2988,7 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3027,7 +3012,7 @@ void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3046,7 +3031,7 @@ void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3065,7 +3050,7 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3089,7 +3074,7 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3113,7 +3098,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3185,7 +3170,7 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");
@ -3206,7 +3191,7 @@ void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
DiffieHellman* diffieHellman = DiffieHellman* diffieHellman =
ObjectWrap::Unwrap<DiffieHellman>(args.This()); WeakObject::Unwrap<DiffieHellman>(args.This());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return ThrowError("Not initialized"); return ThrowError("Not initialized");

62
src/node_crypto.h

@ -32,6 +32,9 @@
#endif #endif
#include "env.h" #include "env.h"
#include "weak-object.h"
#include "weak-object-inl.h"
#include "v8.h" #include "v8.h"
#include <openssl/ssl.h> #include <openssl/ssl.h>
@ -57,7 +60,7 @@ extern X509_STORE* root_cert_store;
// Forward declaration // Forward declaration
class Connection; class Connection;
class SecureContext : public ObjectWrap { class SecureContext : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -90,8 +93,8 @@ class SecureContext : public ObjectWrap {
static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args); static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
explicit SecureContext(Environment* env) SecureContext(Environment* env, v8::Local<v8::Object> wrap)
: ObjectWrap() : WeakObject(env->isolate(), wrap)
, ca_store_(NULL) , ca_store_(NULL)
, ctx_(NULL) , ctx_(NULL)
, env_(env) { , env_(env) {
@ -219,7 +222,7 @@ class SSLWrap {
friend class SecureContext; friend class SecureContext;
}; };
class Connection : public SSLWrap<Connection>, public ObjectWrap { class Connection : public SSLWrap<Connection>, public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -273,15 +276,17 @@ class Connection : public SSLWrap<Connection>, public ObjectWrap {
void SetShutdownFlags(); void SetShutdownFlags();
static Connection* Unwrap(v8::Local<v8::Object> object) { static Connection* Unwrap(v8::Local<v8::Object> object) {
Connection* conn = ObjectWrap::Unwrap<Connection>(object); Connection* conn = WeakObject::Unwrap<Connection>(object);
conn->ClearError(); conn->ClearError();
return conn; return conn;
} }
Connection(Environment* env, Connection(Environment* env,
v8::Local<v8::Object> wrap,
SecureContext* sc, SecureContext* sc,
SSLWrap<Connection>::Kind kind) SSLWrap<Connection>::Kind kind)
: SSLWrap<Connection>(env, sc, kind) : SSLWrap<Connection>(env, sc, kind)
, WeakObject(env->isolate(), wrap)
, bio_read_(NULL) , bio_read_(NULL)
, bio_write_(NULL) , bio_write_(NULL)
, hello_offset_(0) { , hello_offset_(0) {
@ -312,7 +317,7 @@ class Connection : public SSLWrap<Connection>, public ObjectWrap {
friend class SecureContext; friend class SecureContext;
}; };
class CipherBase : public ObjectWrap { class CipherBase : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -339,9 +344,13 @@ class CipherBase : public ObjectWrap {
static void Final(const v8::FunctionCallbackInfo<v8::Value>& args); static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
explicit CipherBase(CipherKind kind) : cipher_(NULL), CipherBase(v8::Isolate* isolate,
initialised_(false), v8::Local<v8::Object> wrap,
kind_(kind) { CipherKind kind)
: WeakObject(isolate, wrap)
, cipher_(NULL)
, initialised_(false)
, kind_(kind) {
} }
~CipherBase() { ~CipherBase() {
@ -356,7 +365,7 @@ class CipherBase : public ObjectWrap {
CipherKind kind_; CipherKind kind_;
}; };
class Hmac : public ObjectWrap { class Hmac : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -370,7 +379,10 @@ class Hmac : public ObjectWrap {
static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args); static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
Hmac() : md_(NULL), initialised_(false) { Hmac(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap)
, md_(NULL)
, initialised_(false) {
} }
~Hmac() { ~Hmac() {
@ -384,7 +396,7 @@ class Hmac : public ObjectWrap {
bool initialised_; bool initialised_;
}; };
class Hash : public ObjectWrap { class Hash : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -396,7 +408,10 @@ class Hash : public ObjectWrap {
static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args); static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
Hash() : md_(NULL), initialised_(false) { Hash(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap)
, md_(NULL)
, initialised_(false) {
} }
~Hash() { ~Hash() {
@ -410,7 +425,7 @@ class Hash : public ObjectWrap {
bool initialised_; bool initialised_;
}; };
class Sign : public ObjectWrap { class Sign : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -427,7 +442,10 @@ class Sign : public ObjectWrap {
static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args); static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
Sign() : md_(NULL), initialised_(false) { Sign(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap)
, md_(NULL)
, initialised_(false) {
} }
~Sign() { ~Sign() {
@ -441,7 +459,7 @@ class Sign : public ObjectWrap {
bool initialised_; bool initialised_;
}; };
class Verify : public ObjectWrap { class Verify : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -458,7 +476,10 @@ class Verify : public ObjectWrap {
static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args); static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
Verify() : md_(NULL), initialised_(false) { Verify(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap)
, md_(NULL)
, initialised_(false) {
} }
~Verify() { ~Verify() {
@ -472,7 +493,7 @@ class Verify : public ObjectWrap {
bool initialised_; bool initialised_;
}; };
class DiffieHellman : public ObjectWrap { class DiffieHellman : public WeakObject {
public: public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target); static void Initialize(Environment* env, v8::Handle<v8::Object> target);
@ -493,7 +514,10 @@ class DiffieHellman : public ObjectWrap {
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
DiffieHellman() : ObjectWrap(), initialised_(false), dh(NULL) { DiffieHellman(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap)
, initialised_(false)
, dh(NULL) {
} }
~DiffieHellman() { ~DiffieHellman() {

27
src/node_http_parser.cc

@ -25,6 +25,8 @@
#include "env.h" #include "env.h"
#include "env-inl.h" #include "env-inl.h"
#include "weak-object.h"
#include "weak-object-inl.h"
#include "v8.h" #include "v8.h"
#include <stdlib.h> // free() #include <stdlib.h> // free()
@ -185,10 +187,10 @@ struct StringPtr {
}; };
class Parser : public ObjectWrap { class Parser : public WeakObject {
public: public:
Parser(Environment* env, enum http_parser_type type) Parser(Environment* env, Local<Object> wrap, enum http_parser_type type)
: ObjectWrap() : WeakObject(env->isolate(), wrap)
, env_(env) , env_(env)
, current_buffer_len_(0) , current_buffer_len_(0)
, current_buffer_data_(NULL) { , current_buffer_data_(NULL) {
@ -252,7 +254,7 @@ class Parser : public ObjectWrap {
HTTP_CB(on_headers_complete) { HTTP_CB(on_headers_complete) {
Local<Object> obj = handle(node_isolate); Local<Object> obj = weak_object(node_isolate);
Local<Value> cb = obj->Get(kOnHeadersComplete); Local<Value> cb = obj->Get(kOnHeadersComplete);
if (!cb->IsFunction()) if (!cb->IsFunction())
@ -313,7 +315,7 @@ class Parser : public ObjectWrap {
HTTP_DATA_CB(on_body) { HTTP_DATA_CB(on_body) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Local<Object> obj = handle(node_isolate); Local<Object> obj = weak_object(node_isolate);
Local<Value> cb = obj->Get(kOnBody); Local<Value> cb = obj->Get(kOnBody);
if (!cb->IsFunction()) if (!cb->IsFunction())
@ -342,7 +344,7 @@ class Parser : public ObjectWrap {
if (num_fields_) if (num_fields_)
Flush(); // Flush trailing HTTP headers. Flush(); // Flush trailing HTTP headers.
Local<Object> obj = handle(node_isolate); Local<Object> obj = weak_object(node_isolate);
Local<Value> cb = obj->Get(kOnMessageComplete); Local<Value> cb = obj->Get(kOnMessageComplete);
if (!cb->IsFunction()) if (!cb->IsFunction())
@ -362,13 +364,10 @@ class Parser : public ObjectWrap {
static void New(const FunctionCallbackInfo<Value>& args) { static void New(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope handle_scope(args.GetIsolate()); HandleScope handle_scope(args.GetIsolate());
http_parser_type type = http_parser_type type =
static_cast<http_parser_type>(args[0]->Int32Value()); static_cast<http_parser_type>(args[0]->Int32Value());
assert(type == HTTP_REQUEST || type == HTTP_RESPONSE); assert(type == HTTP_REQUEST || type == HTTP_RESPONSE);
Parser* parser = new Parser(env, type); new Parser(env, args.This(), type);
parser->Wrap(args.This());
} }
@ -389,7 +388,7 @@ class Parser : public ObjectWrap {
static void Execute(const FunctionCallbackInfo<Value>& args) { static void Execute(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); Parser* parser = WeakObject::Unwrap<Parser>(args.This());
assert(parser->current_buffer_.IsEmpty()); assert(parser->current_buffer_.IsEmpty());
assert(parser->current_buffer_len_ == 0); assert(parser->current_buffer_len_ == 0);
assert(parser->current_buffer_data_ == NULL); assert(parser->current_buffer_data_ == NULL);
@ -443,7 +442,7 @@ class Parser : public ObjectWrap {
static void Finish(const FunctionCallbackInfo<Value>& args) { static void Finish(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); Parser* parser = WeakObject::Unwrap<Parser>(args.This());
assert(parser->current_buffer_.IsEmpty()); assert(parser->current_buffer_.IsEmpty());
parser->got_exception_ = false; parser->got_exception_ = false;
@ -476,7 +475,7 @@ class Parser : public ObjectWrap {
static_cast<http_parser_type>(args[0]->Int32Value()); static_cast<http_parser_type>(args[0]->Int32Value());
assert(type == HTTP_REQUEST || type == HTTP_RESPONSE); assert(type == HTTP_REQUEST || type == HTTP_RESPONSE);
Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); Parser* parser = WeakObject::Unwrap<Parser>(args.This());
// Should always be called from the same context. // Should always be called from the same context.
assert(env == parser->env()); assert(env == parser->env());
parser->Init(type); parser->Init(type);
@ -503,7 +502,7 @@ class Parser : public ObjectWrap {
void Flush() { void Flush() {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Local<Object> obj = handle(node_isolate); Local<Object> obj = weak_object(node_isolate);
Local<Value> cb = obj->Get(kOnHeaders); Local<Value> cb = obj->Get(kOnHeaders);
if (!cb->IsFunction()) if (!cb->IsFunction())

21
src/node_stat_watcher.cc

@ -22,6 +22,8 @@
#include "node_stat_watcher.h" #include "node_stat_watcher.h"
#include "env.h" #include "env.h"
#include "env-inl.h" #include "env-inl.h"
#include "weak-object.h"
#include "weak-object-inl.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -61,8 +63,8 @@ static void Delete(uv_handle_t* handle) {
} }
StatWatcher::StatWatcher(Environment* env) StatWatcher::StatWatcher(Environment* env, Local<Object> wrap)
: ObjectWrap() : WeakObject(env->isolate(), wrap)
, watcher_(new uv_fs_poll_t) , watcher_(new uv_fs_poll_t)
, env_(env) { , env_(env) {
uv_fs_poll_init(env->event_loop(), watcher_); uv_fs_poll_init(env->event_loop(), watcher_);
@ -91,7 +93,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
Integer::New(status, node_isolate) Integer::New(status, node_isolate)
}; };
MakeCallback(env, MakeCallback(env,
wrap->handle(node_isolate), wrap->weak_object(node_isolate),
env->onchange_string(), env->onchange_string(),
ARRAY_SIZE(argv), ARRAY_SIZE(argv),
argv); argv);
@ -102,8 +104,7 @@ void StatWatcher::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall()); assert(args.IsConstructCall());
Environment* env = Environment::GetCurrent(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope handle_scope(args.GetIsolate()); HandleScope handle_scope(args.GetIsolate());
StatWatcher* s = new StatWatcher(env); new StatWatcher(env, args.This());
s->Wrap(args.This());
} }
@ -111,23 +112,23 @@ void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) {
assert(args.Length() == 3); assert(args.Length() == 3);
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
StatWatcher* wrap = ObjectWrap::Unwrap<StatWatcher>(args.This()); StatWatcher* wrap = WeakObject::Unwrap<StatWatcher>(args.This());
String::Utf8Value path(args[0]); String::Utf8Value path(args[0]);
const bool persistent = args[1]->BooleanValue(); const bool persistent = args[1]->BooleanValue();
const uint32_t interval = args[2]->Uint32Value(); const uint32_t interval = args[2]->Uint32Value();
if (!persistent) uv_unref(reinterpret_cast<uv_handle_t*>(wrap->watcher_)); if (!persistent) uv_unref(reinterpret_cast<uv_handle_t*>(wrap->watcher_));
uv_fs_poll_start(wrap->watcher_, Callback, *path, interval); uv_fs_poll_start(wrap->watcher_, Callback, *path, interval);
wrap->Ref(); wrap->ClearWeak();
} }
void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) { void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) {
StatWatcher* wrap = ObjectWrap::Unwrap<StatWatcher>(args.This()); StatWatcher* wrap = WeakObject::Unwrap<StatWatcher>(args.This());
Environment* env = wrap->env(); Environment* env = wrap->env();
Context::Scope context_scope(env->context()); Context::Scope context_scope(env->context());
HandleScope handle_scope(env->isolate()); HandleScope handle_scope(env->isolate());
MakeCallback(env, wrap->handle(node_isolate), env->onstop_string()); MakeCallback(env, wrap->weak_object(node_isolate), env->onstop_string());
wrap->Stop(); wrap->Stop();
} }
@ -135,7 +136,7 @@ void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) {
void StatWatcher::Stop() { void StatWatcher::Stop() {
if (!uv_is_active(reinterpret_cast<uv_handle_t*>(watcher_))) return; if (!uv_is_active(reinterpret_cast<uv_handle_t*>(watcher_))) return;
uv_fs_poll_stop(watcher_); uv_fs_poll_stop(watcher_);
Unref(); MakeWeak();
} }

5
src/node_stat_watcher.h

@ -27,16 +27,17 @@
#include "env.h" #include "env.h"
#include "uv.h" #include "uv.h"
#include "v8.h" #include "v8.h"
#include "weak-object.h"
namespace node { namespace node {
class StatWatcher : public ObjectWrap { class StatWatcher : public WeakObject {
public: public:
static void Initialize(v8::Handle<v8::Object> target); static void Initialize(v8::Handle<v8::Object> target);
inline Environment* env() const { return env_; } inline Environment* env() const { return env_; }
protected: protected:
explicit StatWatcher(Environment* env); StatWatcher(Environment* env, v8::Local<v8::Object> wrap);
virtual ~StatWatcher(); virtual ~StatWatcher();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void New(const v8::FunctionCallbackInfo<v8::Value>& args);

34
src/node_zlib.cc

@ -24,6 +24,9 @@
#include "env.h" #include "env.h"
#include "env-inl.h" #include "env-inl.h"
#include "weak-object.h"
#include "weak-object-inl.h"
#include "v8.h" #include "v8.h"
#include "zlib.h" #include "zlib.h"
@ -64,11 +67,11 @@ void InitZlib(v8::Handle<v8::Object> target);
/** /**
* Deflate/Inflate * Deflate/Inflate
*/ */
class ZCtx : public ObjectWrap { class ZCtx : public WeakObject {
public: public:
ZCtx(Environment* env, node_zlib_mode mode) ZCtx(Environment* env, Local<Object> wrap, node_zlib_mode mode)
: ObjectWrap() : WeakObject(env->isolate(), wrap)
, chunk_size_(0) , chunk_size_(0)
, dictionary_(NULL) , dictionary_(NULL)
, dictionary_len_(0) , dictionary_len_(0)
@ -118,7 +121,7 @@ class ZCtx : public ObjectWrap {
static void Close(const FunctionCallbackInfo<Value>& args) { static void Close(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ZCtx* ctx = WeakObject::Unwrap<ZCtx>(args.This());
ctx->Close(); ctx->Close();
} }
@ -128,13 +131,13 @@ class ZCtx : public ObjectWrap {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
assert(args.Length() == 7); assert(args.Length() == 7);
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ZCtx* ctx = WeakObject::Unwrap<ZCtx>(args.This());
assert(ctx->init_done_ && "write before init"); assert(ctx->init_done_ && "write before init");
assert(ctx->mode_ != NONE && "already finalized"); assert(ctx->mode_ != NONE && "already finalized");
assert(!ctx->write_in_progress_ && "write already in progress"); assert(!ctx->write_in_progress_ && "write already in progress");
ctx->write_in_progress_ = true; ctx->write_in_progress_ = true;
ctx->Ref(); ctx->ClearWeak();
assert(!args[0]->IsUndefined() && "must provide flush value"); assert(!args[0]->IsUndefined() && "must provide flush value");
@ -194,7 +197,7 @@ class ZCtx : public ObjectWrap {
ZCtx::Process, ZCtx::Process,
ZCtx::After); ZCtx::After);
args.GetReturnValue().Set(ctx->persistent()); args.GetReturnValue().Set(ctx->weak_object(node_isolate));
} }
@ -284,11 +287,11 @@ class ZCtx : public ObjectWrap {
ctx->write_in_progress_ = false; ctx->write_in_progress_ = false;
// call the write() cb // call the write() cb
Local<Object> handle = ctx->handle(node_isolate); Local<Object> handle = ctx->weak_object(node_isolate);
Local<Value> args[2] = { avail_in, avail_out }; Local<Value> args[2] = { avail_in, avail_out };
MakeCallback(env, handle, env->callback_string(), ARRAY_SIZE(args), args); MakeCallback(env, handle, env->callback_string(), ARRAY_SIZE(args), args);
ctx->Unref(); ctx->MakeWeak();
} }
static void Error(ZCtx* ctx, const char* message) { static void Error(ZCtx* ctx, const char* message) {
@ -301,7 +304,7 @@ class ZCtx : public ObjectWrap {
message = ctx->strm_.msg; message = ctx->strm_.msg;
} }
Local<Object> handle = ctx->handle(node_isolate); Local<Object> handle = ctx->weak_object(node_isolate);
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
Local<Value> args[2] = { Local<Value> args[2] = {
OneByteString(node_isolate, message), OneByteString(node_isolate, message),
@ -311,7 +314,7 @@ class ZCtx : public ObjectWrap {
// no hope of rescue. // no hope of rescue.
ctx->write_in_progress_ = false; ctx->write_in_progress_ = false;
ctx->Unref(); ctx->MakeWeak();
} }
static void New(const FunctionCallbackInfo<Value>& args) { static void New(const FunctionCallbackInfo<Value>& args) {
@ -327,8 +330,7 @@ class ZCtx : public ObjectWrap {
return ThrowTypeError("Bad argument"); return ThrowTypeError("Bad argument");
} }
ZCtx* ctx = new ZCtx(env, mode); new ZCtx(env, args.This(), mode);
ctx->Wrap(args.This());
} }
// just pull the ints out of the args and call the other Init // just pull the ints out of the args and call the other Init
@ -338,7 +340,7 @@ class ZCtx : public ObjectWrap {
assert((args.Length() == 4 || args.Length() == 5) && assert((args.Length() == 4 || args.Length() == 5) &&
"init(windowBits, level, memLevel, strategy, [dictionary])"); "init(windowBits, level, memLevel, strategy, [dictionary])");
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ZCtx* ctx = WeakObject::Unwrap<ZCtx>(args.This());
int windowBits = args[0]->Uint32Value(); int windowBits = args[0]->Uint32Value();
assert((windowBits >= 8 && windowBits <= 15) && "invalid windowBits"); assert((windowBits >= 8 && windowBits <= 15) && "invalid windowBits");
@ -377,7 +379,7 @@ class ZCtx : public ObjectWrap {
assert(args.Length() == 2 && "params(level, strategy)"); assert(args.Length() == 2 && "params(level, strategy)");
ZCtx* ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ZCtx* ctx = WeakObject::Unwrap<ZCtx>(args.This());
Params(ctx, args[0]->Int32Value(), args[1]->Int32Value()); Params(ctx, args[0]->Int32Value(), args[1]->Int32Value());
} }
@ -385,7 +387,7 @@ class ZCtx : public ObjectWrap {
static void Reset(const FunctionCallbackInfo<Value> &args) { static void Reset(const FunctionCallbackInfo<Value> &args) {
HandleScope scope(node_isolate); HandleScope scope(node_isolate);
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ZCtx* ctx = WeakObject::Unwrap<ZCtx>(args.This());
Reset(ctx); Reset(ctx);
SetDictionary(ctx); SetDictionary(ctx);

18
src/tls_wrap.cc

@ -58,7 +58,7 @@ TLSCallbacks::TLSCallbacks(Environment* env,
Kind kind, Kind kind,
Handle<Object> sc, Handle<Object> sc,
StreamWrapCallbacks* old) StreamWrapCallbacks* old)
: SSLWrap<TLSCallbacks>(env, ObjectWrap::Unwrap<SecureContext>(sc), kind), : SSLWrap<TLSCallbacks>(env, WeakObject::Unwrap<SecureContext>(sc), kind),
StreamWrapCallbacks(old), StreamWrapCallbacks(old),
enc_in_(NULL), enc_in_(NULL),
enc_out_(NULL), enc_out_(NULL),
@ -70,7 +70,7 @@ TLSCallbacks::TLSCallbacks(Environment* env,
shutdown_(false) { shutdown_(false) {
// Persist SecureContext // Persist SecureContext
sc_ = ObjectWrap::Unwrap<SecureContext>(sc); sc_ = WeakObject::Unwrap<SecureContext>(sc);
sc_handle_.Reset(node_isolate, sc); sc_handle_.Reset(node_isolate, sc);
Local<Object> object = env->tls_wrap_constructor_function()->NewInstance(); Local<Object> object = env->tls_wrap_constructor_function()->NewInstance();
@ -236,7 +236,7 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
// There should be a Context::Scope a few stack frames down. // There should be a Context::Scope a few stack frames down.
assert(env->context() == env->isolate()->GetCurrentContext()); assert(env->context() == env->isolate()->GetCurrentContext());
HandleScope handle_scope(env->isolate()); HandleScope handle_scope(env->isolate());
Local<Object> object = c->object(env->isolate()); Local<Object> object = c->weak_object(env->isolate());
if (where & SSL_CB_HANDSHAKE_START) { if (where & SSL_CB_HANDSHAKE_START) {
Local<Value> callback = object->Get(env->onhandshakestart_string()); Local<Value> callback = object->Get(env->onhandshakestart_string());
@ -313,7 +313,7 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
FIXED_ONE_BYTE_STRING(node_isolate, "write cb error, status: "), FIXED_ONE_BYTE_STRING(node_isolate, "write cb error, status: "),
Integer::New(status, node_isolate)->ToString()); Integer::New(status, node_isolate)->ToString());
MakeCallback(env, MakeCallback(env,
callbacks->object(node_isolate), callbacks->weak_object(node_isolate),
env->onerror_string(), env->onerror_string(),
1, 1,
&arg); &arg);
@ -398,7 +398,7 @@ void TLSCallbacks::ClearOut() {
if (!argv.IsEmpty()) { if (!argv.IsEmpty()) {
MakeCallback(env(), MakeCallback(env(),
object(node_isolate), weak_object(node_isolate),
env()->onerror_string(), env()->onerror_string(),
1, 1,
&argv); &argv);
@ -437,7 +437,7 @@ bool TLSCallbacks::ClearIn() {
Handle<Value> argv = GetSSLError(written, &err); Handle<Value> argv = GetSSLError(written, &err);
if (!argv.IsEmpty()) { if (!argv.IsEmpty()) {
MakeCallback(env(), MakeCallback(env(),
object(node_isolate), weak_object(node_isolate),
env()->onerror_string(), env()->onerror_string(),
1, 1,
&argv); &argv);
@ -504,7 +504,7 @@ int TLSCallbacks::DoWrite(WriteWrap* w,
Handle<Value> argv = GetSSLError(written, &err); Handle<Value> argv = GetSSLError(written, &err);
if (!argv.IsEmpty()) { if (!argv.IsEmpty()) {
MakeCallback(env(), MakeCallback(env(),
object(node_isolate), weak_object(node_isolate),
env()->onerror_string(), env()->onerror_string(),
1, 1,
&argv); &argv);
@ -688,7 +688,7 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
if (servername != NULL) { if (servername != NULL) {
// Call the SNI callback and use its return value as context // Call the SNI callback and use its return value as context
Local<Object> object = p->object(node_isolate); Local<Object> object = p->weak_object(node_isolate);
Local<Value> ctx = object->Get(env->sni_context_string()); Local<Value> ctx = object->Get(env->sni_context_string());
if (!ctx->IsObject()) if (!ctx->IsObject())
@ -697,7 +697,7 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
p->sni_context_.Dispose(); p->sni_context_.Dispose();
p->sni_context_.Reset(node_isolate, ctx); p->sni_context_.Reset(node_isolate, ctx);
SecureContext* sc = ObjectWrap::Unwrap<SecureContext>(ctx.As<Object>()); SecureContext* sc = WeakObject::Unwrap<SecureContext>(ctx.As<Object>());
SSL_set_SSL_CTX(s, sc->ctx_); SSL_set_SSL_CTX(s, sc->ctx_);
} }

8
src/tls_wrap.h

@ -64,8 +64,8 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
int DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb); int DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb);
// Just for compliance with Connection // Just for compliance with Connection
inline v8::Local<v8::Object> handle(v8::Isolate* isolate) { inline v8::Local<v8::Object> weak_object(v8::Isolate* isolate) {
return object(isolate); return PersistentToLocal(isolate, persistent());
} }
protected: protected:
@ -123,10 +123,6 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
static int SelectSNIContextCallback(SSL* s, int* ad, void* arg); static int SelectSNIContextCallback(SSL* s, int* ad, void* arg);
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
inline v8::Local<v8::Object> object(v8::Isolate* isolate) {
return PersistentToLocal(isolate, persistent());
}
inline v8::Persistent<v8::Object>& persistent() { inline v8::Persistent<v8::Object>& persistent() {
return object_; return object_;
} }

71
src/weak-object-inl.h

@ -0,0 +1,71 @@
// 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_WEAK_OBJECT_INL_H_
#define SRC_WEAK_OBJECT_INL_H_
#include "weak-object.h"
namespace node {
WeakObject::WeakObject(v8::Isolate* isolate, v8::Local<v8::Object> object)
: weak_object_(isolate, object) {
weak_object_.MarkIndependent();
object->SetAlignedPointerInInternalField(kInternalFieldIndex, this);
MakeWeak();
}
WeakObject::~WeakObject() {
}
v8::Local<v8::Object> WeakObject::weak_object(v8::Isolate* isolate) const {
return v8::Local<v8::Object>::New(isolate, weak_object_);
}
void WeakObject::MakeWeak() {
weak_object_.MakeWeak(this, WeakCallback);
}
void WeakObject::ClearWeak() {
weak_object_.ClearWeak();
}
template <typename TypeName>
TypeName* WeakObject::Unwrap(v8::Local<v8::Object> object) {
// Cast to WeakObject* before casting to TypeName* avoids issues with classes
// that have multiple base classes.
void* p = object->GetAlignedPointerFromInternalField(kInternalFieldIndex);
WeakObject* w = static_cast<WeakObject*>(p);
return static_cast<TypeName*>(w);
}
void WeakObject::WeakCallback(v8::Isolate* isolate,
v8::Persistent<v8::Object>* persistent,
WeakObject* self) {
// Dispose now instead of in the destructor to avoid child classes that call
// `delete this` in their destructor from blowing up.
persistent->Dispose();
delete self;
}
} // namespace node
#endif // SRC_WEAK_OBJECT_INL_H_

54
src/weak-object.h

@ -0,0 +1,54 @@
// 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_WEAK_OBJECT_H_
#define SRC_WEAK_OBJECT_H_
#include "v8.h"
namespace node {
class WeakObject {
public:
// FIXME(bnoordhuis) These methods are public only because the code base
// plays fast and loose with encapsulation.
template <typename TypeName>
inline static TypeName* Unwrap(v8::Local<v8::Object> object);
// Returns the wrapped object. Illegal to call in your destructor.
inline v8::Local<v8::Object> weak_object(v8::Isolate* isolate) const;
protected:
// |object| should be an instance of a v8::ObjectTemplate that has at least
// one internal field reserved with v8::ObjectTemplate::SetInternalFieldCount.
inline WeakObject(v8::Isolate* isolate, v8::Local<v8::Object> object);
virtual inline ~WeakObject();
inline void MakeWeak();
inline void ClearWeak();
private:
inline static void WeakCallback(v8::Isolate* isolate,
v8::Persistent<v8::Object>* persistent,
WeakObject* self);
static const int kInternalFieldIndex = 0;
v8::Persistent<v8::Object> weak_object_;
};
} // namespace node
#endif // SRC_WEAK_OBJECT_H_
Loading…
Cancel
Save