Browse Source

async-wrap: integrate with WeakObject

Making WeakObject inherit from AsyncWrap allows us to peak into almost
all the MakeCallback calls in Node internals.
Trevor Norris 11 years ago
parent
commit
8b8e3b6798
  1. 2
      src/env.h
  2. 7
      src/node_contextify.cc
  3. 78
      src/node_crypto.cc
  4. 44
      src/node_crypto.h
  5. 17
      src/node_http_parser.cc
  6. 13
      src/node_stat_watcher.cc
  7. 2
      src/node_stat_watcher.h
  8. 17
      src/node_zlib.cc
  9. 5
      src/stream_wrap.cc
  10. 2
      src/stream_wrap.h
  11. 47
      src/tls_wrap.cc
  12. 14
      src/tls_wrap.h
  13. 20
      src/weak-object-inl.h
  14. 10
      src/weak-object.h

2
src/env.h

@ -96,6 +96,7 @@ namespace node {
V(onclienthello_string, "onclienthello") \
V(oncomplete_string, "oncomplete") \
V(onconnection_string, "onconnection") \
V(ondone_string, "ondone") \
V(onerror_string, "onerror") \
V(onexit_string, "onexit") \
V(onhandshakedone_string, "onhandshakedone") \
@ -103,6 +104,7 @@ namespace node {
V(onmessage_string, "onmessage") \
V(onnewsession_string, "onnewsession") \
V(onread_string, "onread") \
V(onselect_string, "onselect") \
V(onsignal_string, "onsignal") \
V(onstop_string, "onstop") \
V(path_string, "path") \

7
src/node_contextify.cc

@ -412,8 +412,9 @@ class ContextifyScript : public WeakObject {
return ThrowError("Must call vm.Script as a constructor.");
}
Environment* env = Environment::GetCurrent(args.GetIsolate());
ContextifyScript* contextify_script =
new ContextifyScript(args.GetIsolate(), args.This());
new ContextifyScript(env, args.This());
TryCatch try_catch;
Local<String> code = args[0]->ToString();
@ -605,8 +606,8 @@ class ContextifyScript : public WeakObject {
}
ContextifyScript(Isolate* isolate, Local<Object> object)
: WeakObject(isolate, object) {
ContextifyScript(Environment* env, Local<Object> object)
: WeakObject(env, object) {
}

78
src/node_crypto.cc

@ -845,7 +845,7 @@ int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
HandleScope scope(node_isolate);
Base* w = static_cast<Base*>(SSL_get_app_data(s));
Environment* env = w->env();
Environment* env = w->ssl_env();
if (!w->session_callbacks_)
return 0;
@ -866,11 +866,7 @@ int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
reinterpret_cast<char*>(sess->session_id),
sess->session_id_length);
Local<Value> argv[] = { session, buff };
MakeCallback(env,
w->weak_object(node_isolate),
env->onnewsession_string(),
ARRAY_SIZE(argv),
argv);
w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
return 0;
}
@ -882,7 +878,7 @@ void SSLWrap<Base>::OnClientHello(void* arg,
HandleScope scope(node_isolate);
Base* w = static_cast<Base*>(arg);
Environment* env = w->env();
Environment* env = w->ssl_env();
Local<Object> hello_obj = Object::New();
Local<Object> buff = Buffer::New(
@ -901,11 +897,7 @@ void SSLWrap<Base>::OnClientHello(void* arg,
hello_obj->Set(env->tls_ticket_string(), Boolean::New(hello.has_ticket()));
Local<Value> argv[] = { hello_obj };
MakeCallback(env,
w->weak_object(node_isolate),
env->onclienthello_string(),
ARRAY_SIZE(argv),
argv);
w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
}
@ -916,7 +908,7 @@ void SSLWrap<Base>::GetPeerCertificate(
HandleScope scope(node_isolate);
Base* w = Unwrap<Base>(args.This());
Environment* env = w->env();
Environment* env = w->ssl_env();
Local<Object> info = Object::New();
X509* peer_cert = SSL_get_peer_certificate(w->ssl_);
@ -1109,7 +1101,7 @@ void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Base* w = Unwrap<Base>(args.This());
Environment* env = w->env();
Environment* env = w->ssl_env();
if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
ssize_t slen = Buffer::Length(args[0]);
@ -1258,7 +1250,7 @@ void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Base* w = Unwrap<Base>(args.This());
Environment* env = w->env();
Environment* env = w->ssl_env();
OPENSSL_CONST SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
if (c == NULL)
@ -1432,8 +1424,7 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
HandleScope scope(node_isolate);
Local<Value> exception =
Exception::Error(OneByteString(node_isolate, ssl_error_buf));
weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
ssl_,
@ -1476,8 +1467,7 @@ int Connection::HandleSSLError(const char* func,
} else if (err == SSL_ERROR_ZERO_RETURN) {
Local<Value> exception =
Exception::Error(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN"));
weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
return rv;
} else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
@ -1501,8 +1491,7 @@ int Connection::HandleSSLError(const char* func,
BIO_get_mem_ptr(bio, &mem);
Local<Value> exception =
Exception::Error(OneByteString(node_isolate, mem->data, mem->length));
weak_object(node_isolate)->Set(
FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
BIO_free_all(bio);
}
@ -1519,7 +1508,7 @@ void Connection::ClearError() {
// We should clear the error in JS-land
Local<String> error_key = FIXED_ONE_BYTE_STRING(node_isolate, "error");
Local<Value> error = weak_object(node_isolate)->Get(error_key);
Local<Value> error = object()->Get(error_key);
assert(error->BooleanValue() == false);
#endif // NDEBUG
}
@ -1533,13 +1522,13 @@ void Connection::SetShutdownFlags() {
if (flags & SSL_SENT_SHUTDOWN) {
Local<String> sent_shutdown_key =
FIXED_ONE_BYTE_STRING(node_isolate, "sentShutdown");
weak_object(node_isolate)->Set(sent_shutdown_key, True(node_isolate));
object()->Set(sent_shutdown_key, True(node_isolate));
}
if (flags & SSL_RECEIVED_SHUTDOWN) {
Local<String> received_shutdown_key =
FIXED_ONE_BYTE_STRING(node_isolate, "receivedShutdown");
weak_object(node_isolate)->Set(received_shutdown_key, True(node_isolate));
object()->Set(received_shutdown_key, True(node_isolate));
}
}
@ -1644,10 +1633,8 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
if (!conn->sniObject_.IsEmpty()) {
conn->sniContext_.Dispose();
Local<Object> sni_object =
PersistentToLocal(node_isolate, conn->sniObject_);
Local<Value> arg = PersistentToLocal(node_isolate, conn->servername_);
Local<Value> ret = MakeCallback(env, sni_object, "onselect", 1, &arg);
Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
// If ret is SecureContext
Local<FunctionTemplate> secure_context_constructor_template =
@ -1766,15 +1753,11 @@ void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
HandleScope handle_scope(env->isolate());
if (where & SSL_CB_HANDSHAKE_START) {
MakeCallback(env,
conn->weak_object(node_isolate),
env->onhandshakestart_string());
conn->MakeCallback(env->onhandshakestart_string(), 0, NULL);
}
if (where & SSL_CB_HANDSHAKE_DONE) {
MakeCallback(env,
conn->weak_object(node_isolate),
env->onhandshakedone_string());
conn->MakeCallback(env->onhandshakedone_string(), 0, NULL);
}
}
@ -2088,7 +2071,8 @@ void CipherBase::Initialize(Environment* env, Handle<Object> target) {
void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall() == true);
CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
new CipherBase(args.GetIsolate(), args.This(), kind);
Environment* env = Environment::GetCurrent(args.GetIsolate());
new CipherBase(env, args.This(), kind);
}
@ -2329,7 +2313,8 @@ void Hmac::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Hmac::New(const FunctionCallbackInfo<Value>& args) {
new Hmac(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
new Hmac(env, args.This());
}
@ -2466,7 +2451,8 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
const String::Utf8Value hash_type(args[0]);
Hash* hash = new Hash(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
Hash* hash = new Hash(env, args.This());
if (!hash->HashInit(*hash_type)) {
return ThrowError("Digest method not supported");
}
@ -2565,7 +2551,8 @@ void Sign::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Sign::New(const FunctionCallbackInfo<Value>& args) {
new Sign(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
new Sign(env, args.This());
}
@ -2746,7 +2733,8 @@ void Verify::Initialize(Environment* env, v8::Handle<v8::Object> target) {
void Verify::New(const FunctionCallbackInfo<Value>& args) {
new Verify(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
new Verify(env, args.This());
}
@ -3006,8 +2994,8 @@ void DiffieHellman::DiffieHellmanGroup(
const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
DiffieHellman* diffieHellman =
new DiffieHellman(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
if (args.Length() != 1 || !args[0]->IsString()) {
return ThrowError("No group name given");
@ -3034,8 +3022,9 @@ void DiffieHellman::DiffieHellmanGroup(
void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
DiffieHellman* diffieHellman =
new DiffieHellman(args.GetIsolate(), args.This());
new DiffieHellman(env, args.This());
bool initialized = false;
if (args.Length() > 0) {
@ -3353,7 +3342,7 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
req->obj.Dispose();
Local<Value> argv[2];
EIO_PBKDF2After(req, argv);
MakeCallback(env, obj, "ondone", ARRAY_SIZE(argv), argv);
MakeCallback(env, obj, env->ondone_string(), ARRAY_SIZE(argv), argv);
}
@ -3532,7 +3521,7 @@ void RandomBytesAfter(uv_work_t* work_req, int status) {
Local<Value> argv[2];
RandomBytesCheck(req, argv);
Local<Object> obj = PersistentToLocal(node_isolate, req->obj_);
MakeCallback(env, obj, "ondone", ARRAY_SIZE(argv), argv);
MakeCallback(env, obj, env->ondone_string(), ARRAY_SIZE(argv), argv);
delete req;
}
@ -3664,7 +3653,8 @@ void Certificate::Initialize(Handle<Object> target) {
void Certificate::New(const FunctionCallbackInfo<Value>& args) {
new Certificate(args.GetIsolate(), args.This());
Environment* env = Environment::GetCurrent(args.GetIsolate());
new Certificate(env, args.This());
}

44
src/node_crypto.h

@ -63,10 +63,6 @@ class SecureContext : public WeakObject {
public:
static void Initialize(Environment* env, v8::Handle<v8::Object> target);
inline Environment* env() const {
return env_;
}
X509_STORE* ca_store_;
SSL_CTX* ctx_;
@ -93,10 +89,9 @@ class SecureContext : public WeakObject {
static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
SecureContext(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env->isolate(), wrap),
: WeakObject(env, wrap),
ca_store_(NULL),
ctx_(NULL),
env_(env) {
ctx_(NULL) {
}
void FreeCTXMem() {
@ -119,9 +114,6 @@ class SecureContext : public WeakObject {
~SecureContext() {
FreeCTXMem();
}
private:
Environment* const env_;
};
template <class Base>
@ -202,7 +194,7 @@ class SSLWrap {
void* arg);
#endif // OPENSSL_NPN_NEGOTIATED
inline Environment* env() const {
inline Environment* ssl_env() const {
return env_;
}
@ -279,7 +271,7 @@ class Connection : public SSLWrap<Connection>, public WeakObject {
SecureContext* sc,
SSLWrap<Connection>::Kind kind)
: SSLWrap<Connection>(env, sc, kind),
WeakObject(env->isolate(), wrap),
WeakObject(env, wrap),
bio_read_(NULL),
bio_write_(NULL),
hello_offset_(0) {
@ -337,10 +329,10 @@ class CipherBase : public WeakObject {
static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
CipherBase(v8::Isolate* isolate,
CipherBase(Environment* env,
v8::Local<v8::Object> wrap,
CipherKind kind)
: WeakObject(isolate, wrap),
: WeakObject(env, wrap),
cipher_(NULL),
initialised_(false),
kind_(kind) {
@ -373,8 +365,8 @@ class Hmac : public WeakObject {
static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
Hmac(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap),
Hmac(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap),
md_(NULL),
initialised_(false) {
}
@ -403,8 +395,8 @@ class Hash : public WeakObject {
static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
Hash(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap),
Hash(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap),
md_(NULL),
initialised_(false) {
}
@ -439,8 +431,8 @@ class Sign : public WeakObject {
static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
Sign(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap),
Sign(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap),
md_(NULL),
initialised_(false) {
}
@ -474,8 +466,8 @@ class Verify : public WeakObject {
static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
Verify(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap),
Verify(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap),
md_(NULL),
initialised_(false) {
}
@ -513,8 +505,8 @@ class DiffieHellman : public WeakObject {
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
DiffieHellman(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap),
DiffieHellman(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap),
initialised_(false),
dh(NULL) {
}
@ -547,8 +539,8 @@ class Certificate : public WeakObject {
static void ExportPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ExportChallenge(const v8::FunctionCallbackInfo<v8::Value>& args);
Certificate(v8::Isolate* isolate, v8::Local<v8::Object> wrap)
: WeakObject(isolate, wrap) {
Certificate(Environment* env, v8::Local<v8::Object> wrap)
: WeakObject(env, wrap) {
}
};

17
src/node_http_parser.cc

@ -166,8 +166,7 @@ struct StringPtr {
class Parser : public WeakObject {
public:
Parser(Environment* env, Local<Object> wrap, enum http_parser_type type)
: WeakObject(env->isolate(), wrap),
env_(env),
: WeakObject(env, wrap),
current_buffer_len_(0),
current_buffer_data_(NULL) {
Init(type);
@ -230,7 +229,7 @@ class Parser : public WeakObject {
HTTP_CB(on_headers_complete) {
Local<Object> obj = weak_object(node_isolate);
Local<Object> obj = object();
Local<Value> cb = obj->Get(kOnHeadersComplete);
if (!cb->IsFunction())
@ -291,7 +290,7 @@ class Parser : public WeakObject {
HTTP_DATA_CB(on_body) {
HandleScope scope(node_isolate);
Local<Object> obj = weak_object(node_isolate);
Local<Object> obj = object();
Local<Value> cb = obj->Get(kOnBody);
if (!cb->IsFunction())
@ -320,7 +319,7 @@ class Parser : public WeakObject {
if (num_fields_)
Flush(); // Flush trailing HTTP headers.
Local<Object> obj = weak_object(node_isolate);
Local<Object> obj = object();
Local<Value> cb = obj->Get(kOnMessageComplete);
if (!cb->IsFunction())
@ -491,7 +490,7 @@ class Parser : public WeakObject {
void Flush() {
HandleScope scope(node_isolate);
Local<Object> obj = weak_object(node_isolate);
Local<Object> obj = object();
Local<Value> cb = obj->Get(kOnHeaders);
if (!cb->IsFunction())
@ -522,12 +521,6 @@ class Parser : public WeakObject {
}
inline Environment* env() const {
return env_;
}
Environment* const env_;
http_parser parser_;
StringPtr fields_[32]; // header fields
StringPtr values_[32]; // header values

13
src/node_stat_watcher.cc

@ -66,9 +66,8 @@ static void Delete(uv_handle_t* handle) {
StatWatcher::StatWatcher(Environment* env, Local<Object> wrap)
: WeakObject(env->isolate(), wrap),
watcher_(new uv_fs_poll_t),
env_(env) {
: WeakObject(env, wrap),
watcher_(new uv_fs_poll_t) {
uv_fs_poll_init(env->event_loop(), watcher_);
watcher_->data = static_cast<void*>(this);
}
@ -94,11 +93,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
BuildStatsObject(env, prev),
Integer::New(status, node_isolate)
};
MakeCallback(env,
wrap->weak_object(node_isolate),
env->onchange_string(),
ARRAY_SIZE(argv),
argv);
wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
}
@ -131,7 +126,7 @@ void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) {
Environment* env = wrap->env();
Context::Scope context_scope(env->context());
HandleScope handle_scope(env->isolate());
MakeCallback(env, wrap->weak_object(node_isolate), env->onstop_string());
wrap->MakeCallback(env->onstop_string(), 0, NULL);
wrap->Stop();
}

2
src/node_stat_watcher.h

@ -33,7 +33,6 @@ namespace node {
class StatWatcher : public WeakObject {
public:
static void Initialize(v8::Handle<v8::Object> target);
inline Environment* env() const { return env_; }
protected:
StatWatcher(Environment* env, v8::Local<v8::Object> wrap);
@ -51,7 +50,6 @@ class StatWatcher : public WeakObject {
void Stop();
uv_fs_poll_t* watcher_;
Environment* const env_;
};
} // namespace node

17
src/node_zlib.cc

@ -73,11 +73,10 @@ class ZCtx : public WeakObject {
public:
ZCtx(Environment* env, Local<Object> wrap, node_zlib_mode mode)
: WeakObject(env->isolate(), wrap),
: WeakObject(env, wrap),
chunk_size_(0),
dictionary_(NULL),
dictionary_len_(0),
env_(env),
err_(0),
flush_(0),
init_done_(false),
@ -95,11 +94,6 @@ class ZCtx : public WeakObject {
Close();
}
inline Environment* env() const {
return env_;
}
void Close() {
assert(!write_in_progress_ && "write in progress");
assert(init_done_ && "close before init");
@ -200,7 +194,7 @@ class ZCtx : public WeakObject {
ZCtx::Process,
ZCtx::After);
args.GetReturnValue().Set(ctx->weak_object(node_isolate));
args.GetReturnValue().Set(ctx->object());
}
@ -290,9 +284,8 @@ class ZCtx : public WeakObject {
ctx->write_in_progress_ = false;
// call the write() cb
Local<Object> handle = ctx->weak_object(node_isolate);
Local<Value> args[2] = { avail_in, avail_out };
MakeCallback(env, handle, env->callback_string(), ARRAY_SIZE(args), args);
ctx->MakeCallback(env->callback_string(), ARRAY_SIZE(args), args);
ctx->Unref();
}
@ -307,13 +300,12 @@ class ZCtx : public WeakObject {
message = ctx->strm_.msg;
}
Local<Object> handle = ctx->weak_object(node_isolate);
HandleScope scope(node_isolate);
Local<Value> args[2] = {
OneByteString(node_isolate, message),
Number::New(ctx->err_)
};
MakeCallback(env, handle, env->onerror_string(), ARRAY_SIZE(args), args);
ctx->MakeCallback(env->onerror_string(), ARRAY_SIZE(args), args);
// no hope of rescue.
ctx->write_in_progress_ = false;
@ -540,7 +532,6 @@ class ZCtx : public WeakObject {
int chunk_size_;
Bytef* dictionary_;
size_t dictionary_len_;
Environment* const env_;
int err_;
int flush_;
bool init_done_;

5
src/stream_wrap.cc

@ -603,9 +603,4 @@ int StreamWrapCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {
return uv_shutdown(&req_wrap->req_, wrap()->stream(), cb);
}
Handle<Object> StreamWrapCallbacks::Self() {
return wrap()->object();
}
} // namespace node

2
src/stream_wrap.h

@ -88,8 +88,6 @@ class StreamWrapCallbacks {
uv_handle_type pending);
virtual int DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb);
v8::Handle<v8::Object> Self();
protected:
inline StreamWrap* wrap() const {
return wrap_;

47
src/tls_wrap.cc

@ -20,6 +20,8 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tls_wrap.h"
#include "async-wrap.h"
#include "async-wrap-inl.h"
#include "node_buffer.h" // Buffer
#include "node_crypto.h" // SecureContext
#include "node_crypto_bio.h" // NodeBIO
@ -62,6 +64,7 @@ TLSCallbacks::TLSCallbacks(Environment* env,
StreamWrapCallbacks* old)
: SSLWrap<TLSCallbacks>(env, Unwrap<SecureContext>(sc), kind),
StreamWrapCallbacks(old),
AsyncWrap(env, env->tls_wrap_constructor_function()->NewInstance()),
enc_in_(NULL),
enc_out_(NULL),
clear_in_(NULL),
@ -75,9 +78,7 @@ TLSCallbacks::TLSCallbacks(Environment* env,
sc_ = Unwrap<SecureContext>(sc);
sc_handle_.Reset(node_isolate, sc);
Local<Object> object = env->tls_wrap_constructor_function()->NewInstance();
persistent().Reset(node_isolate, object);
node::Wrap<TLSCallbacks>(object, this);
node::Wrap<TLSCallbacks>(object(), this);
// Initialize queue for clearIn writes
QUEUE_INIT(&write_item_queue_);
@ -237,12 +238,12 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
// There should be a Context::Scope a few stack frames down.
assert(env->context() == env->isolate()->GetCurrentContext());
HandleScope handle_scope(env->isolate());
Local<Object> object = c->weak_object(env->isolate());
Local<Object> object = c->object();
if (where & SSL_CB_HANDSHAKE_START) {
Local<Value> callback = object->Get(env->onhandshakestart_string());
if (callback->IsFunction()) {
MakeCallback(env, object, callback.As<Function>());
c->MakeCallback(callback.As<Function>(), 0, NULL);
}
}
@ -250,7 +251,7 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
c->established_ = true;
Local<Value> callback = object->Get(env->onhandshakedone_string());
if (callback->IsFunction()) {
MakeCallback(env, object, callback.As<Function>());
c->MakeCallback(callback.As<Function>(), 0, NULL);
}
}
}
@ -313,11 +314,7 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
Local<Value> arg = String::Concat(
FIXED_ONE_BYTE_STRING(node_isolate, "write cb error, status: "),
Integer::New(status, node_isolate)->ToString());
MakeCallback(env,
callbacks->weak_object(node_isolate),
env->onerror_string(),
1,
&arg);
callbacks->MakeCallback(env->onerror_string(), 1, &arg);
callbacks->InvokeQueued(status);
return;
}
@ -385,11 +382,7 @@ void TLSCallbacks::ClearOut() {
Integer::New(read, node_isolate),
Buffer::New(env(), out, read)
};
MakeCallback(env(),
Self(),
env()->onread_string(),
ARRAY_SIZE(argv),
argv);
wrap()->MakeCallback(env()->onread_string(), ARRAY_SIZE(argv), argv);
}
} while (read > 0);
@ -398,11 +391,7 @@ void TLSCallbacks::ClearOut() {
Handle<Value> argv = GetSSLError(read, &err);
if (!argv.IsEmpty()) {
MakeCallback(env(),
weak_object(node_isolate),
env()->onerror_string(),
1,
&argv);
MakeCallback(env()->onerror_string(), 1, &argv);
}
}
}
@ -437,11 +426,7 @@ bool TLSCallbacks::ClearIn() {
int err;
Handle<Value> argv = GetSSLError(written, &err);
if (!argv.IsEmpty()) {
MakeCallback(env(),
weak_object(node_isolate),
env()->onerror_string(),
1,
&argv);
MakeCallback(env()->onerror_string(), 1, &argv);
}
return false;
@ -504,11 +489,7 @@ int TLSCallbacks::DoWrite(WriteWrap* w,
HandleScope handle_scope(env()->isolate());
Handle<Value> argv = GetSSLError(written, &err);
if (!argv.IsEmpty()) {
MakeCallback(env(),
weak_object(node_isolate),
env()->onerror_string(),
1,
&argv);
MakeCallback(env()->onerror_string(), 1, &argv);
return -1;
}
@ -547,7 +528,7 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,
Context::Scope context_scope(env()->context());
HandleScope handle_scope(env()->isolate());
Local<Value> arg = Integer::New(nread, node_isolate);
MakeCallback(env(), Self(), env()->onread_string(), 1, &arg);
wrap()->MakeCallback(env()->onread_string(), 1, &arg);
return;
}
@ -685,7 +666,7 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
if (servername != NULL) {
// Call the SNI callback and use its return value as context
Local<Object> object = p->weak_object(node_isolate);
Local<Object> object = p->object();
Local<Value> ctx = object->Get(env->sni_context_string());
if (!ctx->IsObject())

14
src/tls_wrap.h

@ -25,6 +25,7 @@
#include "node.h"
#include "node_crypto.h" // SSLWrap
#include "async-wrap.h"
#include "env.h"
#include "queue.h"
#include "stream_wrap.h"
@ -42,7 +43,8 @@ namespace crypto {
}
class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
public StreamWrapCallbacks {
public StreamWrapCallbacks,
public AsyncWrap {
public:
static void Initialize(v8::Handle<v8::Object> target,
v8::Handle<v8::Value> unused,
@ -63,11 +65,6 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
uv_handle_type pending);
int DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb);
// Just for compliance with Connection
inline v8::Local<v8::Object> weak_object(v8::Isolate* isolate) {
return PersistentToLocal(isolate, persistent());
}
protected:
static const int kClearOutChunkSize = 1024;
@ -123,13 +120,8 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
static int SelectSNIContextCallback(SSL* s, int* ad, void* arg);
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
inline v8::Persistent<v8::Object>& persistent() {
return object_;
}
crypto::SecureContext* sc_;
v8::Persistent<v8::Object> sc_handle_;
v8::Persistent<v8::Object> object_;
BIO* enc_in_;
BIO* enc_out_;
NodeBIO* clear_in_;

20
src/weak-object-inl.h

@ -23,14 +23,16 @@
#define SRC_WEAK_OBJECT_INL_H_
#include "weak-object.h"
#include "async-wrap.h"
#include "async-wrap-inl.h"
#include "util.h"
#include "util-inl.h"
namespace node {
WeakObject::WeakObject(v8::Isolate* isolate, v8::Local<v8::Object> object)
: weak_object_(isolate, object) {
weak_object_.MarkIndependent();
WeakObject::WeakObject(Environment* env, v8::Local<v8::Object> object)
: AsyncWrap(env, object) {
persistent().MarkIndependent();
// The pointer is resolved as void*.
Wrap<WeakObject>(object, this);
@ -40,16 +42,12 @@ WeakObject::WeakObject(v8::Isolate* isolate, v8::Local<v8::Object> object)
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);
persistent().MakeWeak(this, WeakCallback);
}
void WeakObject::ClearWeak() {
weak_object_.ClearWeak();
persistent().ClearWeak();
}
void WeakObject::WeakCallback(v8::Isolate* isolate,
@ -57,7 +55,9 @@ void WeakObject::WeakCallback(v8::Isolate* isolate,
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();
// Dispose the class member instead of the argument or else the IsEmpty()
// check in ~AsyncWrap will fail.
self->persistent().Dispose();
delete self;
}

10
src/weak-object.h

@ -22,18 +22,17 @@
#ifndef SRC_WEAK_OBJECT_H_
#define SRC_WEAK_OBJECT_H_
#include "async-wrap.h"
#include "env.h"
#include "v8.h"
namespace node {
class WeakObject {
public:
// Returns the wrapped object. Illegal to call in your destructor.
inline v8::Local<v8::Object> weak_object(v8::Isolate* isolate) const;
class WeakObject : public AsyncWrap {
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);
inline WeakObject(Environment* env, v8::Local<v8::Object> object);
virtual inline ~WeakObject();
inline void MakeWeak();
inline void ClearWeak();
@ -41,7 +40,6 @@ class WeakObject {
inline static void WeakCallback(v8::Isolate* isolate,
v8::Persistent<v8::Object>* persistent,
WeakObject* self);
v8::Persistent<v8::Object> weak_object_;
};
} // namespace node

Loading…
Cancel
Save