From 819690fd983d61f90cdf05714a30782fe3b553cd Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Tue, 9 Dec 2014 05:29:47 +0100 Subject: [PATCH] src: all wraps now use actual FunctionTemplate Instead of simply creating a new v8::Object to contain the connection information, instantiate a new instance of a FunctionTemplate. This will allow future improvements for debugging and performance probes. Additionally, the "provider" argument in the ReqWrap constructor is no longer optional. PR-URL: https://github.com/joyent/node/pull/8110 Signed-off-by: Trevor Norris Reviewed-by: Fedor Indutny Reviewed-by: Alexis Campailla Reviewed-by: Julien Gilli --- lib/child_process.js | 4 +- lib/dgram.js | 5 +- lib/dns.js | 26 ++--- lib/fs.js | 142 +++++++++++++++++++-------- lib/net.js | 23 +++-- src/async-wrap.h | 41 ++++---- src/cares_wrap.cc | 64 +++++++++--- src/node_file.cc | 117 ++++++++++++---------- src/pipe_wrap.cc | 31 +++++- src/req_wrap.h | 4 +- src/stream_wrap.cc | 29 +++++- src/stream_wrap.h | 23 ++++- src/tcp_wrap.cc | 35 +++++-- src/udp_wrap.cc | 16 ++- test/internet/test-dns.js | 5 +- test/simple/test-tcp-wrap-connect.js | 6 +- test/simple/test-tcp-wrap-listen.js | 4 +- 17 files changed, 407 insertions(+), 168 deletions(-) diff --git a/lib/child_process.js b/lib/child_process.js index 68eae613b5..a37d2f2d41 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -29,6 +29,7 @@ var assert = require('assert'); var util = require('util'); var Process = process.binding('process_wrap').Process; +var WriteWrap = process.binding('stream_wrap').WriteWrap; var uv = process.binding('uv'); var spawn_sync; // Lazy-loaded process.binding('spawn_sync') @@ -475,7 +476,8 @@ function setupChannel(target, channel) { return; } - var req = { oncomplete: nop }; + var req = new WriteWrap(); + req.oncomplete = nop; var string = JSON.stringify(message) + '\n'; var err = channel.writeUtf8String(req, string, handle); diff --git a/lib/dgram.js b/lib/dgram.js index 4d6228e1dd..defa144bd1 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -27,6 +27,7 @@ var events = require('events'); var constants = require('constants'); var UDP = process.binding('udp_wrap').UDP; +var SendWrap = process.binding('udp_wrap').SendWrap; var BIND_STATE_UNBOUND = 0; var BIND_STATE_BINDING = 1; @@ -319,7 +320,9 @@ Socket.prototype.send = function(buffer, self.emit('error', ex); } else if (self._handle) { - var req = { buffer: buffer, length: length }; // Keep reference alive. + var req = new SendWrap(); + req.buffer = buffer; // Keep reference alive. + req.length = length; if (callback) { req.callback = callback; req.oncomplete = afterSend; diff --git a/lib/dns.js b/lib/dns.js index f758e345de..4534971852 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -27,6 +27,9 @@ var util = require('util'); var cares = process.binding('cares_wrap'); var uv = process.binding('uv'); +var GetAddrInfoReqWrap = cares.GetAddrInfoReqWrap; +var GetNameInfoReqWrap = cares.GetNameInfoReqWrap; + var isIp = net.isIP; @@ -144,12 +147,11 @@ exports.lookup = function lookup(hostname, options, callback) { return {}; } - var req = { - callback: callback, - family: family, - hostname: hostname, - oncomplete: onlookup - }; + var req = new GetAddrInfoReqWrap(); + req.callback = callback; + req.family = family; + req.hostname = hostname; + req.oncomplete = onlookup; var err = cares.getaddrinfo(req, hostname, family, hints); if (err) { @@ -180,12 +182,12 @@ exports.lookupService = function(host, port, callback) { callback = makeAsync(callback); - var req = { - callback: callback, - host: host, - port: port, - oncomplete: onlookupservice - }; + var req = new GetNameInfoReqWrap(); + req.callback = callback; + req.host = host; + req.port = port; + req.oncomplete = onlookupservice; + var err = cares.getnameinfo(req, host, port); if (err) throw errnoException(err, 'getnameinfo', host); diff --git a/lib/fs.js b/lib/fs.js index 77dd2a9efa..c9fe6129c5 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -35,6 +35,7 @@ var constants = process.binding('constants'); var fs = exports; var Stream = require('stream').Stream; var EventEmitter = require('events').EventEmitter; +var FSReqWrap = binding.FSReqWrap; var Readable = Stream.Readable; var Writable = Stream.Writable; @@ -184,7 +185,9 @@ fs.Stats.prototype.isSocket = function() { fs.exists = function(path, callback) { if (!nullCheck(path, cb)) return; - binding.stat(pathModule._makeLong(path), cb); + var req = new FSReqWrap(); + req.oncomplete = cb; + binding.stat(pathModule._makeLong(path), req); function cb(err, stats) { if (callback) callback(err ? false : true); } @@ -423,7 +426,9 @@ Object.defineProperty(exports, '_stringToFlags', { // list to make the arguments clear. fs.close = function(fd, callback) { - binding.close(fd, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.close(fd, req); }; fs.closeSync = function(fd) { @@ -445,10 +450,14 @@ fs.open = function(path, flags, mode, callback) { mode = modeNum(mode, 438 /*=0666*/); if (!nullCheck(path, callback)) return; + + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.open(pathModule._makeLong(path), stringToFlags(flags), mode, - callback); + req); }; fs.openSync = function(path, flags, mode) { @@ -484,7 +493,10 @@ fs.read = function(fd, buffer, offset, length, position, callback) { callback && callback(err, bytesRead || 0, buffer); } - binding.read(fd, buffer, offset, length, position, wrapper); + var req = new FSReqWrap(); + req.oncomplete = wrapper; + + binding.read(fd, buffer, offset, length, position, req); }; fs.readSync = function(fd, buffer, offset, length, position) { @@ -517,6 +529,16 @@ fs.readSync = function(fd, buffer, offset, length, position) { // OR // fs.write(fd, string[, position[, encoding]], callback); fs.write = function(fd, buffer, offset, length, position, callback) { + function strWrapper(err, written) { + // Retain a reference to buffer so that it can't be GC'ed too soon. + callback(err, written || 0, buffer); + } + + function bufWrapper(err, written) { + // retain reference to string in case it's external + callback(err, written || 0, buffer); + } + if (util.isBuffer(buffer)) { // if no position is passed then assume null if (util.isFunction(position)) { @@ -524,11 +546,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) { position = null; } callback = maybeCallback(callback); - var wrapper = function(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - }; - return binding.writeBuffer(fd, buffer, offset, length, position, wrapper); + var req = new FSReqWrap(); + req.oncomplete = strWrapper; + return binding.writeBuffer(fd, buffer, offset, length, position, req); } if (util.isString(buffer)) @@ -543,11 +563,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) { length = 'utf8'; } callback = maybeCallback(position); - position = function(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - }; - return binding.writeString(fd, buffer, offset, length, position); + var req = new FSReqWrap(); + req.oncomplete = bufWrapper; + return binding.writeString(fd, buffer, offset, length, req); }; // usage: @@ -571,9 +589,11 @@ fs.rename = function(oldPath, newPath, callback) { callback = makeCallback(callback); if (!nullCheck(oldPath, callback)) return; if (!nullCheck(newPath, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; binding.rename(pathModule._makeLong(oldPath), pathModule._makeLong(newPath), - callback); + req); }; fs.renameSync = function(oldPath, newPath) { @@ -585,8 +605,9 @@ fs.renameSync = function(oldPath, newPath) { fs.truncate = function(path, len, callback) { if (util.isNumber(path)) { - // legacy - return fs.ftruncate(path, len, callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + return fs.ftruncate(path, len, req); } if (util.isFunction(len)) { callback = len; @@ -594,14 +615,17 @@ fs.truncate = function(path, len, callback) { } else if (util.isUndefined(len)) { len = 0; } + callback = maybeCallback(callback); fs.open(path, 'r+', function(er, fd) { if (er) return callback(er); - binding.ftruncate(fd, len, function(er) { + var req = new FSReqWrap(); + req.oncomplete = function ftruncateCb(er) { fs.close(fd, function(er2) { callback(er || er2); }); - }); + }; + binding.ftruncate(fd, len, req); }); }; @@ -630,7 +654,9 @@ fs.ftruncate = function(fd, len, callback) { } else if (util.isUndefined(len)) { len = 0; } - binding.ftruncate(fd, len, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.ftruncate(fd, len, req); }; fs.ftruncateSync = function(fd, len) { @@ -641,9 +667,11 @@ fs.ftruncateSync = function(fd, len) { }; fs.rmdir = function(path, callback) { - callback = makeCallback(callback); + callback = maybeCallback(callback); if (!nullCheck(path, callback)) return; - binding.rmdir(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.rmdir(pathModule._makeLong(path), req); }; fs.rmdirSync = function(path) { @@ -652,7 +680,9 @@ fs.rmdirSync = function(path) { }; fs.fdatasync = function(fd, callback) { - binding.fdatasync(fd, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.fdatasync(fd, req); }; fs.fdatasyncSync = function(fd) { @@ -660,7 +690,9 @@ fs.fdatasyncSync = function(fd) { }; fs.fsync = function(fd, callback) { - binding.fsync(fd, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.fsync(fd, req); }; fs.fsyncSync = function(fd) { @@ -671,9 +703,11 @@ fs.mkdir = function(path, mode, callback) { if (util.isFunction(mode)) callback = mode; callback = makeCallback(callback); if (!nullCheck(path, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; binding.mkdir(pathModule._makeLong(path), modeNum(mode, 511 /*=0777*/), - callback); + req); }; fs.mkdirSync = function(path, mode) { @@ -685,7 +719,9 @@ fs.mkdirSync = function(path, mode) { fs.readdir = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.readdir(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.readdir(pathModule._makeLong(path), req); }; fs.readdirSync = function(path) { @@ -694,19 +730,25 @@ fs.readdirSync = function(path) { }; fs.fstat = function(fd, callback) { - binding.fstat(fd, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.fstat(fd, req); }; fs.lstat = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.lstat(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.lstat(pathModule._makeLong(path), req); }; fs.stat = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.stat(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.stat(pathModule._makeLong(path), req); }; fs.fstatSync = function(fd) { @@ -726,7 +768,9 @@ fs.statSync = function(path) { fs.readlink = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.readlink(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.readlink(pathModule._makeLong(path), req); }; fs.readlinkSync = function(path) { @@ -756,10 +800,13 @@ fs.symlink = function(destination, path, type_, callback) { if (!nullCheck(destination, callback)) return; if (!nullCheck(path, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.symlink(preprocessSymlinkDestination(destination, type, path), pathModule._makeLong(path), type, - callback); + req); }; fs.symlinkSync = function(destination, path, type) { @@ -778,9 +825,12 @@ fs.link = function(srcpath, dstpath, callback) { if (!nullCheck(srcpath, callback)) return; if (!nullCheck(dstpath, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.link(pathModule._makeLong(srcpath), pathModule._makeLong(dstpath), - callback); + req); }; fs.linkSync = function(srcpath, dstpath) { @@ -793,7 +843,9 @@ fs.linkSync = function(srcpath, dstpath) { fs.unlink = function(path, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.unlink(pathModule._makeLong(path), callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.unlink(pathModule._makeLong(path), req); }; fs.unlinkSync = function(path) { @@ -802,7 +854,9 @@ fs.unlinkSync = function(path) { }; fs.fchmod = function(fd, mode, callback) { - binding.fchmod(fd, modeNum(mode), makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.fchmod(fd, modeNum(mode), req); }; fs.fchmodSync = function(fd, mode) { @@ -852,9 +906,11 @@ if (constants.hasOwnProperty('O_SYMLINK')) { fs.chmod = function(path, mode, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; binding.chmod(pathModule._makeLong(path), modeNum(mode), - callback); + req); }; fs.chmodSync = function(path, mode) { @@ -881,7 +937,9 @@ if (constants.hasOwnProperty('O_SYMLINK')) { } fs.fchown = function(fd, uid, gid, callback) { - binding.fchown(fd, uid, gid, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.fchown(fd, uid, gid, req); }; fs.fchownSync = function(fd, uid, gid) { @@ -891,7 +949,9 @@ fs.fchownSync = function(fd, uid, gid) { fs.chown = function(path, uid, gid, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; - binding.chown(pathModule._makeLong(path), uid, gid, callback); + var req = new FSReqWrap(); + req.oncomplete = callback; + binding.chown(pathModule._makeLong(path), uid, gid, req); }; fs.chownSync = function(path, uid, gid) { @@ -917,10 +977,12 @@ fs._toUnixTimestamp = toUnixTimestamp; fs.utimes = function(path, atime, mtime, callback) { callback = makeCallback(callback); if (!nullCheck(path, callback)) return; + var req = new FSReqWrap(); + req.oncomplete = callback; binding.utimes(pathModule._makeLong(path), toUnixTimestamp(atime), toUnixTimestamp(mtime), - callback); + req); }; fs.utimesSync = function(path, atime, mtime) { @@ -933,7 +995,9 @@ fs.utimesSync = function(path, atime, mtime) { fs.futimes = function(fd, atime, mtime, callback) { atime = toUnixTimestamp(atime); mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime, makeCallback(callback)); + var req = new FSReqWrap(); + req.oncomplete = makeCallback(callback); + binding.futimes(fd, atime, mtime, req); }; fs.futimesSync = function(fd, atime, mtime) { diff --git a/lib/net.js b/lib/net.js index 061d7b959d..6256b022b9 100644 --- a/lib/net.js +++ b/lib/net.js @@ -30,6 +30,11 @@ var cares = process.binding('cares_wrap'); var uv = process.binding('uv'); var Pipe = process.binding('pipe_wrap').Pipe; +var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap; +var PipeConnectWrap = process.binding('pipe_wrap').PipeConnectWrap; +var ShutdownWrap = process.binding('stream_wrap').ShutdownWrap; +var WriteWrap = process.binding('stream_wrap').WriteWrap; + var cluster; var errnoException = util._errnoException; @@ -239,7 +244,8 @@ function onSocketFinish() { if (!this._handle || !this._handle.shutdown) return this.destroy(); - var req = { oncomplete: afterShutdown }; + var req = new ShutdownWrap(); + req.oncomplete = afterShutdown; var err = this._handle.shutdown(req); if (err) @@ -661,7 +667,9 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) { return false; } - var req = { oncomplete: afterWrite, async: false }; + var req = new WriteWrap(); + req.oncomplete = afterWrite; + req.async = false; var err; if (writev) { @@ -842,14 +850,9 @@ function connect(self, address, port, addressType, localAddress, localPort) { } } - var req = { - oncomplete: afterConnect, - port: undefined, - address: undefined, - localAddress: undefined, - localPort: undefined - }; if (addressType === 6 || addressType === 4) { + var req = new TCPConnectWrap(); + req.oncomplete = afterConnect; port = port | 0; if (port <= 0 || port > 65535) throw new RangeError('Port should be > 0 and < 65536'); @@ -862,7 +865,9 @@ function connect(self, address, port, addressType, localAddress, localPort) { err = self._handle.connect(req, address, port); } } else { + var req = new PipeConnectWrap(); req.address = address; + req.oncomplete = afterConnect; err = self._handle.connect(req, address, afterConnect); } diff --git a/src/async-wrap.h b/src/async-wrap.h index 30e49946e7..a069533718 100644 --- a/src/async-wrap.h +++ b/src/async-wrap.h @@ -31,25 +31,28 @@ namespace node { class AsyncWrap : public BaseObject { public: enum ProviderType { - PROVIDER_NONE = 1 << 0, - PROVIDER_CARES = 1 << 1, - PROVIDER_CONNECTWRAP = 1 << 2, - PROVIDER_CRYPTO = 1 << 3, - PROVIDER_FSEVENTWRAP = 1 << 4, - PROVIDER_GETADDRINFOREQWRAP = 1 << 5, - PROVIDER_PIPEWRAP = 1 << 6, - PROVIDER_PROCESSWRAP = 1 << 7, - PROVIDER_REQWRAP = 1 << 8, - PROVIDER_SHUTDOWNWRAP = 1 << 9, - PROVIDER_SIGNALWRAP = 1 << 10, - PROVIDER_STATWATCHER = 1 << 11, - PROVIDER_TCPWRAP = 1 << 12, - PROVIDER_TIMERWRAP = 1 << 13, - PROVIDER_TLSWRAP = 1 << 14, - PROVIDER_TTYWRAP = 1 << 15, - PROVIDER_UDPWRAP = 1 << 16, - PROVIDER_ZLIB = 1 << 17, - PROVIDER_GETNAMEINFOREQWRAP = 1 << 18 + PROVIDER_NONE, + PROVIDER_CARES, + PROVIDER_CONNECTWRAP, + PROVIDER_CRYPTO, + PROVIDER_FSEVENTWRAP, + PROVIDER_FSREQWRAP, + PROVIDER_GETADDRINFOREQWRAP, + PROVIDER_GETNAMEINFOREQWRAP, + PROVIDER_PIPEWRAP, + PROVIDER_PROCESSWRAP, + PROVIDER_QUERYWRAP, + PROVIDER_REQWRAP, + PROVIDER_SHUTDOWNWRAP, + PROVIDER_SIGNALWRAP, + PROVIDER_STATWATCHER, + PROVIDER_TCPWRAP, + PROVIDER_TIMERWRAP, + PROVIDER_TLSWRAP, + PROVIDER_TTYWRAP, + PROVIDER_UDPWRAP, + PROVIDER_WRITEWRAP, + PROVIDER_ZLIB }; inline AsyncWrap(Environment* env, diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index a2db630b98..f9761f9605 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -54,6 +54,7 @@ using v8::Context; using v8::EscapableHandleScope; using v8::Function; using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; using v8::Integer; @@ -63,8 +64,39 @@ using v8::Object; using v8::String; using v8::Value; -typedef class ReqWrap GetAddrInfoReqWrap; -typedef class ReqWrap GetNameInfoReqWrap; + +class GetAddrInfoReqWrap : public ReqWrap { + public: + GetAddrInfoReqWrap(Environment* env, Local req_wrap_obj); +}; + +GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env, + Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP) { + Wrap(req_wrap_obj, this); +} + + +static void NewGetAddrInfoReqWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} + + +class GetNameInfoReqWrap : public ReqWrap { + public: + GetNameInfoReqWrap(Environment* env, Local req_wrap_obj); +}; + +GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env, + Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) { + Wrap(req_wrap_obj, this); +} + + +static void NewGetNameInfoReqWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) { @@ -228,7 +260,7 @@ static Local HostentToNames(Environment* env, struct hostent* host) { class QueryWrap : public AsyncWrap { public: QueryWrap(Environment* env, Local req_wrap_obj) - : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_CARES) { + : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP) { if (env->in_domain()) req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0)); } @@ -1031,10 +1063,7 @@ static void GetAddrInfo(const FunctionCallbackInfo& args) { abort(); } - GetAddrInfoReqWrap* req_wrap = - new GetAddrInfoReqWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_GETADDRINFOREQWRAP); + GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj); struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); @@ -1070,10 +1099,7 @@ static void GetNameInfo(const FunctionCallbackInfo& args) { CHECK(uv_ip4_addr(*ip, port, reinterpret_cast(&addr)) == 0 || uv_ip6_addr(*ip, port, reinterpret_cast(&addr)) == 0); - GetNameInfoReqWrap* req_wrap = - new GetNameInfoReqWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP); + GetNameInfoReqWrap* req_wrap = new GetNameInfoReqWrap(env, req_wrap_obj); int err = uv_getnameinfo(env->event_loop(), &req_wrap->req_, @@ -1263,6 +1289,22 @@ static void Initialize(Handle target, Integer::New(env->isolate(), AI_ADDRCONFIG)); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_V4MAPPED"), Integer::New(env->isolate(), AI_V4MAPPED)); + + Local aiw = + FunctionTemplate::New(env->isolate(), NewGetAddrInfoReqWrap); + aiw->InstanceTemplate()->SetInternalFieldCount(1); + aiw->SetClassName( + FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"), + aiw->GetFunction()); + + Local niw = + FunctionTemplate::New(env->isolate(), NewGetNameInfoReqWrap); + niw->InstanceTemplate()->SetInternalFieldCount(1); + niw->SetClassName( + FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"), + niw->GetFunction()); } } // namespace cares_wrap diff --git a/src/node_file.cc b/src/node_file.cc index 6d9e3ec91b..9f03f011c9 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -70,11 +70,15 @@ class FSReqWrap: public ReqWrap { void* operator new(size_t size) { return new char[size]; } void* operator new(size_t size, char* storage) { return storage; } - FSReqWrap(Environment* env, const char* syscall, char* data = nullptr) - : ReqWrap(env, Object::New(env->isolate())), + FSReqWrap(Environment* env, + Local req, + const char* syscall, + char* data = nullptr) + : ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP), syscall_(syscall), data_(data), dest_len_(0) { + Wrap(object(), this); } void ReleaseEarly() { @@ -97,6 +101,11 @@ class FSReqWrap: public ReqWrap { }; +static void NewFSReqWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} + + #define ASSERT_OFFSET(a) \ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ return env->ThrowTypeError("Not an integer"); \ @@ -253,35 +262,35 @@ struct fs_req_wrap { }; -#define ASYNC_DEST_CALL(func, callback, dest_path, ...) \ +#define ASYNC_DEST_CALL(func, req, dest_path, ...) \ Environment* env = Environment::GetCurrent(args); \ FSReqWrap* req_wrap; \ char* dest_str = (dest_path); \ int dest_len = dest_str == nullptr ? 0 : strlen(dest_str); \ char* storage = new char[sizeof(*req_wrap) + dest_len]; \ - req_wrap = new(storage) FSReqWrap(env, #func); \ + CHECK(req->IsObject()); \ + req_wrap = new(storage) FSReqWrap(env, req.As(), #func); \ req_wrap->dest_len(dest_len); \ if (dest_str != nullptr) { \ memcpy(const_cast(req_wrap->dest()), \ dest_str, \ dest_len + 1); \ } \ - int err = uv_fs_ ## func(env->event_loop() , \ + int err = uv_fs_ ## func(env->event_loop(), \ &req_wrap->req_, \ __VA_ARGS__, \ After); \ - req_wrap->object()->Set(env->oncomplete_string(), callback); \ req_wrap->Dispatched(); \ if (err < 0) { \ - uv_fs_t* req = &req_wrap->req_; \ - req->result = err; \ - req->path = nullptr; \ - After(req); \ + uv_fs_t* uv_req = &req_wrap->req_; \ + uv_req->result = err; \ + uv_req->path = nullptr; \ + After(uv_req); \ } \ args.GetReturnValue().Set(req_wrap->persistent()); -#define ASYNC_CALL(func, callback, ...) \ - ASYNC_DEST_CALL(func, callback, nullptr, __VA_ARGS__) \ +#define ASYNC_CALL(func, req, ...) \ + ASYNC_DEST_CALL(func, req, nullptr, __VA_ARGS__) \ #define SYNC_DEST_CALL(func, path, dest, ...) \ fs_req_wrap req_wrap; \ @@ -317,7 +326,7 @@ static void Close(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(close, args[1], fd) } else { SYNC_CALL(close, 0, fd) @@ -432,7 +441,7 @@ static void Stat(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(stat, args[1], *path) } else { SYNC_CALL(stat, *path, *path) @@ -451,7 +460,7 @@ static void LStat(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(lstat, args[1], *path) } else { SYNC_CALL(lstat, *path, *path) @@ -469,7 +478,7 @@ static void FStat(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(fstat, args[1], fd) } else { SYNC_CALL(fstat, 0, fd) @@ -506,7 +515,7 @@ static void Symlink(const FunctionCallbackInfo& args) { } } - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_DEST_CALL(symlink, args[3], *path, *dest, *path, flags) } else { SYNC_DEST_CALL(symlink, *dest, *path, *dest, *path, flags) @@ -529,7 +538,7 @@ static void Link(const FunctionCallbackInfo& args) { node::Utf8Value orig_path(args[0]); node::Utf8Value new_path(args[1]); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_DEST_CALL(link, args[2], *new_path, *orig_path, *new_path) } else { SYNC_DEST_CALL(link, *orig_path, *new_path, *orig_path, *new_path) @@ -546,7 +555,7 @@ static void ReadLink(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(readlink, args[1], *path) } else { SYNC_CALL(readlink, *path, *path) @@ -572,7 +581,7 @@ static void Rename(const FunctionCallbackInfo& args) { node::Utf8Value old_path(args[0]); node::Utf8Value new_path(args[1]); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_DEST_CALL(rename, args[2], *new_path, *old_path, *new_path) } else { SYNC_DEST_CALL(rename, *old_path, *new_path, *old_path, *new_path) @@ -591,7 +600,7 @@ static void FTruncate(const FunctionCallbackInfo& args) { ASSERT_TRUNCATE_LENGTH(args[1]); int64_t len = GET_TRUNCATE_LENGTH(args[1]); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_CALL(ftruncate, args[2], fd, len) } else { SYNC_CALL(ftruncate, 0, fd, len) @@ -607,7 +616,7 @@ static void Fdatasync(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(fdatasync, args[1], fd) } else { SYNC_CALL(fdatasync, 0, fd) @@ -623,7 +632,7 @@ static void Fsync(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(fsync, args[1], fd) } else { SYNC_CALL(fsync, 0, fd) @@ -640,7 +649,7 @@ static void Unlink(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(unlink, args[1], *path) } else { SYNC_CALL(unlink, *path, *path) @@ -657,7 +666,7 @@ static void RMDir(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(rmdir, args[1], *path) } else { SYNC_CALL(rmdir, *path, *path) @@ -674,7 +683,7 @@ static void MKDir(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); int mode = static_cast(args[1]->Int32Value()); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_CALL(mkdir, args[2], *path, mode) } else { SYNC_CALL(mkdir, *path, *path, mode) @@ -691,7 +700,7 @@ static void ReadDir(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); - if (args[1]->IsFunction()) { + if (args[1]->IsObject()) { ASYNC_CALL(scandir, args[1], *path, 0 /*flags*/) } else { SYNC_CALL(scandir, *path, *path, 0 /*flags*/) @@ -739,7 +748,7 @@ static void Open(const FunctionCallbackInfo& args) { int flags = args[1]->Int32Value(); int mode = static_cast(args[2]->Int32Value()); - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_CALL(open, args[3], *path, flags, mode) } else { SYNC_CALL(open, *path, *path, flags, mode) @@ -770,7 +779,7 @@ static void WriteBuffer(const FunctionCallbackInfo& args) { size_t off = args[2]->Uint32Value(); size_t len = args[3]->Uint32Value(); int64_t pos = GET_OFFSET(args[4]); - Local cb = args[5]; + Local req = args[5]; if (off > buffer_length) return env->ThrowRangeError("offset out of bounds"); @@ -785,8 +794,8 @@ static void WriteBuffer(const FunctionCallbackInfo& args) { uv_buf_t uvbuf = uv_buf_init(const_cast(buf), len); - if (cb->IsFunction()) { - ASYNC_CALL(write, cb, fd, &uvbuf, 1, pos) + if (req->IsObject()) { + ASYNC_CALL(write, req, fd, &uvbuf, 1, pos) return; } @@ -809,7 +818,7 @@ static void WriteString(const FunctionCallbackInfo& args) { if (!args[0]->IsInt32()) return env->ThrowTypeError("First argument must be file descriptor"); - Local cb; + Local req; Local string = args[1]; int fd = args[0]->Int32Value(); char* buf = nullptr; @@ -831,18 +840,19 @@ static void WriteString(const FunctionCallbackInfo& args) { must_free = true; } pos = GET_OFFSET(args[2]); - cb = args[4]; + req = args[4]; uv_buf_t uvbuf = uv_buf_init(const_cast(buf), len); - if (!cb->IsFunction()) { + if (!req->IsObject()) { SYNC_CALL(write, nullptr, fd, &uvbuf, 1, pos) if (must_free) delete[] buf; return args.GetReturnValue().Set(SYNC_RESULT); } - FSReqWrap* req_wrap = new FSReqWrap(env, "write", must_free ? buf : nullptr); + FSReqWrap* req_wrap = + new FSReqWrap(env, req.As(), "write", must_free ? buf : nullptr); int err = uv_fs_write(env->event_loop(), &req_wrap->req_, fd, @@ -850,13 +860,12 @@ static void WriteString(const FunctionCallbackInfo& args) { 1, pos, After); - req_wrap->object()->Set(env->oncomplete_string(), cb); req_wrap->Dispatched(); if (err < 0) { - uv_fs_t* req = &req_wrap->req_; - req->result = err; - req->path = nullptr; - After(req); + uv_fs_t* uv_req = &req_wrap->req_; + uv_req->result = err; + uv_req->path = nullptr; + After(uv_req); } return args.GetReturnValue().Set(req_wrap->persistent()); @@ -884,7 +893,7 @@ static void Read(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - Local cb; + Local req; size_t len; int64_t pos; @@ -914,10 +923,10 @@ static void Read(const FunctionCallbackInfo& args) { uv_buf_t uvbuf = uv_buf_init(const_cast(buf), len); - cb = args[5]; + req = args[5]; - if (cb->IsFunction()) { - ASYNC_CALL(read, cb, fd, &uvbuf, 1, pos); + if (req->IsObject()) { + ASYNC_CALL(read, req, fd, &uvbuf, 1, pos); } else { SYNC_CALL(read, 0, fd, &uvbuf, 1, pos) args.GetReturnValue().Set(SYNC_RESULT); @@ -937,7 +946,7 @@ static void Chmod(const FunctionCallbackInfo& args) { node::Utf8Value path(args[0]); int mode = static_cast(args[1]->Int32Value()); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_CALL(chmod, args[2], *path, mode); } else { SYNC_CALL(chmod, *path, *path, mode); @@ -957,7 +966,7 @@ static void FChmod(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); int mode = static_cast(args[1]->Int32Value()); - if (args[2]->IsFunction()) { + if (args[2]->IsObject()) { ASYNC_CALL(fchmod, args[2], fd, mode); } else { SYNC_CALL(fchmod, 0, fd, mode); @@ -989,7 +998,7 @@ static void Chown(const FunctionCallbackInfo& args) { uv_uid_t uid = static_cast(args[1]->Uint32Value()); uv_gid_t gid = static_cast(args[2]->Uint32Value()); - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_CALL(chown, args[3], *path, uid, gid); } else { SYNC_CALL(chown, *path, *path, uid, gid); @@ -1021,7 +1030,7 @@ static void FChown(const FunctionCallbackInfo& args) { uv_uid_t uid = static_cast(args[1]->Uint32Value()); uv_gid_t gid = static_cast(args[2]->Uint32Value()); - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_CALL(fchown, args[3], fd, uid, gid); } else { SYNC_CALL(fchown, 0, fd, uid, gid); @@ -1050,7 +1059,7 @@ static void UTimes(const FunctionCallbackInfo& args) { const double atime = static_cast(args[1]->NumberValue()); const double mtime = static_cast(args[2]->NumberValue()); - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_CALL(utime, args[3], *path, atime, mtime); } else { SYNC_CALL(utime, *path, *path, atime, mtime); @@ -1078,7 +1087,7 @@ static void FUTimes(const FunctionCallbackInfo& args) { const double atime = static_cast(args[1]->NumberValue()); const double mtime = static_cast(args[2]->NumberValue()); - if (args[3]->IsFunction()) { + if (args[3]->IsObject()) { ASYNC_CALL(futime, args[3], fd, atime, mtime); } else { SYNC_CALL(futime, 0, fd, atime, mtime); @@ -1135,6 +1144,14 @@ void InitFs(Handle target, env->SetMethod(target, "futimes", FUTimes); StatWatcher::Initialize(env, target); + + // Create FunctionTemplate for FSReqWrap + Local fst = + FunctionTemplate::New(env->isolate(), NewFSReqWrap); + fst->InstanceTemplate()->SetInternalFieldCount(1); + fst->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap"), + fst->GetFunction()); } } // end namespace node diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index c99114b77a..a46060cb8b 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -50,8 +50,23 @@ using v8::String; using v8::Undefined; using v8::Value; + // TODO(bnoordhuis) share with TCPWrap? -typedef class ReqWrap ConnectWrap; +class PipeConnectWrap : public ReqWrap { + public: + PipeConnectWrap(Environment* env, Local req_wrap_obj); +}; + + +PipeConnectWrap::PipeConnectWrap(Environment* env, Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPEWRAP) { + Wrap(req_wrap_obj, this); +} + + +static void NewPipeConnectWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} uv_pipe_t* PipeWrap::UVHandle() { @@ -115,6 +130,14 @@ void PipeWrap::Initialize(Handle target, target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction()); env->set_pipe_constructor_template(t); + + // Create FunctionTemplate for PipeConnectWrap. + Local cwt = + FunctionTemplate::New(env->isolate(), NewPipeConnectWrap); + cwt->InstanceTemplate()->SetInternalFieldCount(1); + cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"), + cwt->GetFunction()); } @@ -206,7 +229,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) { // TODO(bnoordhuis) Maybe share this with TCPWrap? void PipeWrap::AfterConnect(uv_connect_t* req, int status) { - ConnectWrap* req_wrap = static_cast(req->data); + PipeConnectWrap* req_wrap = static_cast(req->data); PipeWrap* wrap = static_cast(req->handle->data); CHECK_EQ(req_wrap->env(), wrap->env()); Environment* env = wrap->env(); @@ -267,9 +290,7 @@ void PipeWrap::Connect(const FunctionCallbackInfo& args) { Local req_wrap_obj = args[0].As(); node::Utf8Value name(args[1]); - ConnectWrap* req_wrap = new ConnectWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_CONNECTWRAP); + PipeConnectWrap* req_wrap = new PipeConnectWrap(env, req_wrap_obj); uv_pipe_connect(&req_wrap->req_, &wrap->handle_, *name, diff --git a/src/req_wrap.h b/src/req_wrap.h index 48d62657bd..22263fac7c 100644 --- a/src/req_wrap.h +++ b/src/req_wrap.h @@ -36,8 +36,8 @@ class ReqWrap : public AsyncWrap { public: ReqWrap(Environment* env, v8::Handle object, - AsyncWrap::ProviderType provider = AsyncWrap::PROVIDER_REQWRAP) - : AsyncWrap(env, object, AsyncWrap::PROVIDER_REQWRAP) { + AsyncWrap::ProviderType provider) + : AsyncWrap(env, object, provider) { if (env->in_domain()) object->Set(env->domain_string(), env->domain_array()->Get(0)); diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index f39739cd2f..9d56793b1d 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -43,6 +43,7 @@ using v8::Array; using v8::Context; using v8::EscapableHandleScope; using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; using v8::Integer; @@ -56,6 +57,27 @@ using v8::Undefined; using v8::Value; +void StreamWrap::Initialize(Handle target, + Handle unused, + Handle context) { + Environment* env = Environment::GetCurrent(context); + + Local sw = + FunctionTemplate::New(env->isolate(), ShutdownWrap::NewShutdownWrap); + sw->InstanceTemplate()->SetInternalFieldCount(1); + sw->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"), + sw->GetFunction()); + + Local ww = + FunctionTemplate::New(env->isolate(), WriteWrap::NewWriteWrap); + ww->InstanceTemplate()->SetInternalFieldCount(1); + ww->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"), + ww->GetFunction()); +} + + StreamWrap::StreamWrap(Environment* env, Local object, uv_stream_t* stream, @@ -88,6 +110,7 @@ void StreamWrap::UpdateWriteQueueSize() { object()->Set(env()->write_queue_size_string(), write_queue_size); } + void StreamWrap::ReadStart(const FunctionCallbackInfo& args) { StreamWrap* wrap = Unwrap(args.Holder()); if (!IsAlive(wrap)) @@ -564,9 +587,7 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo& args) { CHECK(args[0]->IsObject()); Local req_wrap_obj = args[0].As(); - ShutdownWrap* req_wrap = new ShutdownWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_SHUTDOWNWRAP); + ShutdownWrap* req_wrap = new ShutdownWrap(env, req_wrap_obj); int err = wrap->callbacks()->DoShutdown(req_wrap, AfterShutdown); req_wrap->Dispatched(); if (err) @@ -752,3 +773,5 @@ int StreamWrapCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) { } } // namespace node + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(stream_wrap, node::StreamWrap::Initialize) diff --git a/src/stream_wrap.h b/src/stream_wrap.h index 26d9890bc9..726d7f26b7 100644 --- a/src/stream_wrap.h +++ b/src/stream_wrap.h @@ -33,15 +33,26 @@ namespace node { // Forward declaration class StreamWrap; -typedef class ReqWrap ShutdownWrap; +class ShutdownWrap : public ReqWrap { + public: + ShutdownWrap(Environment* env, v8::Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_SHUTDOWNWRAP) { + Wrap(req_wrap_obj, this); + } + + static void NewShutdownWrap(const v8::FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); + } +}; class WriteWrap: public ReqWrap { public: // TODO(trevnorris): WrapWrap inherits from ReqWrap, which I've globbed // into the same provider. How should these be broken apart? WriteWrap(Environment* env, v8::Local obj, StreamWrap* wrap) - : ReqWrap(env, obj), + : ReqWrap(env, obj, AsyncWrap::PROVIDER_WRITEWRAP), wrap_(wrap) { + Wrap(obj, this); } void* operator new(size_t size, char* storage) { return storage; } @@ -54,6 +65,10 @@ class WriteWrap: public ReqWrap { return wrap_; } + static void NewWriteWrap(const v8::FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); + } + private: // People should not be using the non-placement new and delete operator on a // WriteWrap. Ensure this never happens. @@ -105,6 +120,10 @@ class StreamWrapCallbacks { class StreamWrap : public HandleWrap { public: + static void Initialize(v8::Handle target, + v8::Handle unused, + v8::Handle context); + void OverrideCallbacks(StreamWrapCallbacks* callbacks, bool gc) { StreamWrapCallbacks* old = callbacks_; callbacks_ = callbacks; diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 4da37ab66f..f17ebcef8a 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -52,7 +52,22 @@ using v8::String; using v8::Undefined; using v8::Value; -typedef class ReqWrap ConnectWrap; + +class TCPConnectWrap : public ReqWrap { + public: + TCPConnectWrap(Environment* env, Local req_wrap_obj); +}; + + +TCPConnectWrap::TCPConnectWrap(Environment* env, Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPWRAP) { + Wrap(req_wrap_obj, this); +} + + +static void NewTCPConnectWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} Local TCPWrap::Instantiate(Environment* env) { @@ -129,6 +144,14 @@ void TCPWrap::Initialize(Handle target, target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"), t->GetFunction()); env->set_tcp_constructor_template(t); + + // Create FunctionTemplate for TCPConnectWrap. + Local cwt = + FunctionTemplate::New(env->isolate(), NewTCPConnectWrap); + cwt->InstanceTemplate()->SetInternalFieldCount(1); + cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"), + cwt->GetFunction()); } @@ -319,7 +342,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) { void TCPWrap::AfterConnect(uv_connect_t* req, int status) { - ConnectWrap* req_wrap = static_cast(req->data); + TCPConnectWrap* req_wrap = static_cast(req->data); TCPWrap* wrap = static_cast(req->handle->data); CHECK_EQ(req_wrap->env(), wrap->env()); Environment* env = wrap->env(); @@ -363,9 +386,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo& args) { int err = uv_ip4_addr(*ip_address, port, &addr); if (err == 0) { - ConnectWrap* req_wrap = new ConnectWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_CONNECTWRAP); + TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj); err = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, reinterpret_cast(&addr), @@ -396,9 +417,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo& args) { int err = uv_ip6_addr(*ip_address, port, &addr); if (err == 0) { - ConnectWrap* req_wrap = new ConnectWrap(env, - req_wrap_obj, - AsyncWrap::PROVIDER_CONNECTWRAP); + TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj); err = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, reinterpret_cast(&addr), diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index fa047eccc9..9fbf391207 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -62,8 +62,9 @@ class SendWrap : public ReqWrap { SendWrap::SendWrap(Environment* env, Local req_wrap_obj, bool have_callback) - : ReqWrap(env, req_wrap_obj), + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_UDPWRAP), have_callback_(have_callback) { + Wrap(req_wrap_obj, this); } @@ -72,6 +73,11 @@ inline bool SendWrap::have_callback() const { } +static void NewSendWrap(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); +} + + UDPWrap::UDPWrap(Environment* env, Handle object) : HandleWrap(env, object, @@ -120,6 +126,14 @@ void UDPWrap::Initialize(Handle target, target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction()); env->set_udp_constructor_function(t->GetFunction()); + + // Create FunctionTemplate for SendWrap + Local swt = + FunctionTemplate::New(env->isolate(), NewSendWrap); + swt->InstanceTemplate()->SetInternalFieldCount(1); + swt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap")); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap"), + swt->GetFunction()); } diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index 60227df7ca..623a845c03 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -632,8 +632,9 @@ var getaddrinfoCallbackCalled = false; console.log('looking up nodejs.org...'); -var req = {}; -var err = process.binding('cares_wrap').getaddrinfo(req, 'nodejs.org', 4); +var cares = process.binding('cares_wrap'); +var req = new cares.GetAddrInfoReqWrap(); +var err = cares.getaddrinfo(req, 'nodejs.org', 4); req.oncomplete = function(err, domains) { assert.strictEqual(err, 0); diff --git a/test/simple/test-tcp-wrap-connect.js b/test/simple/test-tcp-wrap-connect.js index 43fb37ac70..9e915d243b 100644 --- a/test/simple/test-tcp-wrap-connect.js +++ b/test/simple/test-tcp-wrap-connect.js @@ -22,11 +22,13 @@ var common = require('../common'); var assert = require('assert'); var TCP = process.binding('tcp_wrap').TCP; +var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap; +var ShutdownWrap = process.binding('stream_wrap').ShutdownWrap; function makeConnection() { var client = new TCP(); - var req = {}; + var req = new TCPConnectWrap(); var err = client.connect(req, '127.0.0.1', common.PORT); assert.equal(err, 0); @@ -36,7 +38,7 @@ function makeConnection() { assert.equal(req, req_); console.log('connected'); - var shutdownReq = {}; + var shutdownReq = new ShutdownWrap(); var err = client.shutdown(shutdownReq); assert.equal(err, 0); diff --git a/test/simple/test-tcp-wrap-listen.js b/test/simple/test-tcp-wrap-listen.js index fb3175a008..5801368ba1 100644 --- a/test/simple/test-tcp-wrap-listen.js +++ b/test/simple/test-tcp-wrap-listen.js @@ -23,6 +23,7 @@ var common = require('../common'); var assert = require('assert'); var TCP = process.binding('tcp_wrap').TCP; +var WriteWrap = process.binding('stream_wrap').WriteWrap; var server = new TCP(); @@ -55,7 +56,8 @@ server.onconnection = function(err, client) { assert.equal(0, client.writeQueueSize); - var req = { async: false }; + var req = new WriteWrap(); + req.async = false; var err = client.writeBuffer(req, buffer); assert.equal(err, 0); client.pendingWrites.push(req);