diff --git a/lib/child_process.js b/lib/child_process.js index 4840c9e2bac..c4345f90c2a 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -27,6 +27,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') @@ -473,7 +474,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 aae2f51bc86..d1bfa14caa0 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -25,6 +25,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; @@ -317,7 +318,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 4eb34d6651b..18023fab162 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -25,6 +25,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; @@ -142,12 +145,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) { @@ -178,12 +180,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 3301a6af847..a97ba3aa639 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -33,6 +33,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; @@ -182,7 +183,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); } @@ -421,7 +424,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) { @@ -443,10 +448,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) { @@ -482,7 +491,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) { @@ -515,6 +527,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)) { @@ -522,11 +544,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)) @@ -541,11 +561,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: @@ -569,9 +587,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) { @@ -583,8 +603,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; @@ -592,14 +613,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); }); }; @@ -628,7 +652,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) { @@ -639,9 +665,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) { @@ -650,7 +678,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) { @@ -658,7 +688,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) { @@ -669,9 +701,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) { @@ -683,7 +717,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) { @@ -692,19 +728,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) { @@ -724,7 +766,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) { @@ -752,10 +796,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), pathModule._makeLong(path), type, - callback); + req); }; fs.symlinkSync = function(destination, path, type) { @@ -774,9 +821,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) { @@ -789,7 +839,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) { @@ -798,7 +850,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) { @@ -848,9 +902,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) { @@ -877,7 +933,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) { @@ -887,7 +945,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) { @@ -913,10 +973,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) { @@ -929,7 +991,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 34de98bc3c0..fac78f8c04d 100644 --- a/lib/net.js +++ b/lib/net.js @@ -28,6 +28,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; @@ -218,7 +223,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) @@ -641,7 +647,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) { @@ -821,8 +829,9 @@ function connect(self, address, port, addressType, localAddress, localPort) { } } - var req = { oncomplete: afterConnect }; 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'); @@ -833,6 +842,8 @@ function connect(self, address, port, addressType, localAddress, localPort) { err = self._handle.connect(req, address, port); } } else { + var req = new PipeConnectWrap(); + req.oncomplete = afterConnect; err = self._handle.connect(req, address, afterConnect); } diff --git a/src/async-wrap.h b/src/async-wrap.h index b1f1fef3bde..f53246f38de 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 66b4806e7ef..64974adfcbb 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -55,6 +55,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; @@ -64,8 +65,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) { @@ -229,7 +261,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)); } @@ -1037,10 +1069,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)); @@ -1077,10 +1106,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_, @@ -1273,6 +1299,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 de43b92e6e0..8ce8f4205bb 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -71,11 +71,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 = NULL) - : ReqWrap(env, Object::New(env->isolate())), + FSReqWrap(Environment* env, + Local req, + const char* syscall, + char* data = NULL) + : ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP), syscall_(syscall), data_(data), dest_len_(0) { + Wrap(object(), this); } void ReleaseEarly() { @@ -98,6 +102,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"); \ @@ -256,35 +265,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.GetIsolate()); \ FSReqWrap* req_wrap; \ char* dest_str = (dest_path); \ int dest_len = dest_str == NULL ? 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 != NULL) { \ 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 = NULL; \ - After(req); \ + uv_fs_t* uv_req = &req_wrap->req_; \ + uv_req->result = err; \ + uv_req->path = NULL; \ + After(uv_req); \ } \ args.GetReturnValue().Set(req_wrap->persistent()); -#define ASYNC_CALL(func, callback, ...) \ - ASYNC_DEST_CALL(func, callback, NULL, __VA_ARGS__) \ +#define ASYNC_CALL(func, req, ...) \ + ASYNC_DEST_CALL(func, req, NULL, __VA_ARGS__) \ #define SYNC_DEST_CALL(func, path, dest, ...) \ fs_req_wrap req_wrap; \ @@ -321,7 +330,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) @@ -437,7 +446,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) @@ -457,7 +466,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) @@ -476,7 +485,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) @@ -514,7 +523,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) @@ -538,7 +547,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) @@ -556,7 +565,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) @@ -583,7 +592,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) @@ -603,7 +612,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) @@ -620,7 +629,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) @@ -637,7 +646,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) @@ -655,7 +664,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) @@ -673,7 +682,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) @@ -691,7 +700,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) @@ -709,7 +718,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*/) @@ -758,7 +767,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) @@ -790,7 +799,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"); @@ -805,8 +814,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; } @@ -830,7 +839,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 = NULL; @@ -852,18 +861,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, NULL, 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 : NULL); + FSReqWrap* req_wrap = + new FSReqWrap(env, req.As(), "write", must_free ? buf : NULL); int err = uv_fs_write(env->event_loop(), &req_wrap->req_, fd, @@ -871,7 +881,6 @@ 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_; @@ -906,7 +915,7 @@ static void Read(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); - Local cb; + Local req; size_t len; int64_t pos; @@ -936,10 +945,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); @@ -960,7 +969,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); @@ -981,7 +990,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); @@ -1014,7 +1023,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); @@ -1047,7 +1056,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); @@ -1077,7 +1086,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); @@ -1106,7 +1115,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); @@ -1164,6 +1173,14 @@ void InitFs(Handle target, NODE_SET_METHOD(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 05472de5d92..e9f4fbeb9b3 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() { @@ -119,6 +134,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()); } @@ -224,7 +247,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); assert(req_wrap->env() == wrap->env()); Environment* env = wrap->env(); @@ -287,9 +310,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 df4ed2ced1a..8c818e634a8 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 fe3e82799df..b02c58999d7 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, @@ -89,6 +111,7 @@ void StreamWrap::UpdateWriteQueueSize() { object()->Set(env()->write_queue_size_string(), write_queue_size); } + void StreamWrap::ReadStart(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args.GetIsolate()); HandleScope scope(env->isolate()); @@ -560,9 +583,7 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo& args) { assert(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) @@ -744,3 +765,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 34e2799357d..aefb7707513 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 09671d0095e..34aecefd3dd 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -52,7 +52,22 @@ using v8::Undefined; using v8::Value; using v8::Boolean; -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) { @@ -135,6 +150,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()); } @@ -359,7 +382,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); assert(req_wrap->env() == wrap->env()); Environment* env = wrap->env(); @@ -404,9 +427,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), @@ -438,9 +459,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 f0d49133397..1df8da425d8 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) { + assert(args.IsConstructCall()); +} + + UDPWrap::UDPWrap(Environment* env, Handle object) : HandleWrap(env, object, @@ -124,11 +130,19 @@ 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()); } void UDPWrap::New(const FunctionCallbackInfo& args) { - assert(args.IsConstructCall()); + CHECK(args.IsConstructCall()); HandleScope handle_scope(args.GetIsolate()); Environment* env = Environment::GetCurrent(args.GetIsolate()); new UDPWrap(env, args.This()); diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index 60227df7ca6..623a845c03f 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 43fb37ac701..9e915d243ba 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 fb3175a008a..5801368ba1e 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);