Local<Object> handle =
Promise::constructor_template->GetFunction()->NewInstance();
- Promise *promise = new Promise(handle);
- ObjectWrap::InformV8ofAllocation(promise);
+ Promise *promise = new Promise();
+ promise->Wrap(handle);
promise->Attach();
ev_ref(EV_DEFAULT_UC);
public:
static void Initialize (v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template;
- virtual size_t size (void) { return sizeof(EventEmitter); };
bool Emit (const char *type, int argc, v8::Handle<v8::Value> argv[]);
protected:
- EventEmitter (v8::Handle<v8::Object> handle)
- : ObjectWrap(handle) { }
+ EventEmitter () : ObjectWrap() { }
};
class Promise : public EventEmitter {
public:
static void Initialize (v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template;
- virtual size_t size (void) { return sizeof(Promise); };
bool EmitSuccess (int argc, v8::Handle<v8::Value> argv[]);
bool EmitError (int argc, v8::Handle<v8::Value> argv[]);
protected:
- Promise (v8::Handle<v8::Object> handle) : EventEmitter(handle) { }
+ Promise () : EventEmitter() { }
};
} // namespace node
{
HandleScope scope;
- HTTPConnection *connection = new HTTPConnection(args.This(), HTTP_RESPONSE);
- ObjectWrap::InformV8ofAllocation(connection);
+ HTTPConnection *connection = new HTTPConnection(HTTP_RESPONSE);
+ connection->Wrap(args.This());
return args.This();
}
{
HandleScope scope;
- HTTPConnection *connection = new HTTPConnection(args.This(), HTTP_REQUEST);
- ObjectWrap::InformV8ofAllocation(connection);
+ HTTPConnection *connection = new HTTPConnection(HTTP_REQUEST);
+ connection->Wrap(args.This());
return args.This();
}
return 0;
}
-HTTPConnection::HTTPConnection (Handle<Object> handle, enum http_parser_type type)
- : Connection(handle)
-{
- http_parser_init (&parser_, type);
- parser_.on_message_begin = on_message_begin;
- parser_.on_uri = on_uri;
- parser_.on_header_field = on_header_field;
- parser_.on_header_value = on_header_value;
- parser_.on_headers_complete = on_headers_complete;
- parser_.on_body = on_body;
- parser_.on_message_complete = on_message_complete;
- parser_.data = this;
-}
-
Persistent<FunctionTemplate> HTTPServer::constructor_template;
void
{
HandleScope scope;
- HTTPServer *s = new HTTPServer(args.This());
- ObjectWrap::InformV8ofAllocation(s);
+ HTTPServer *server = new HTTPServer();
+ server->Wrap(args.This());
return args.This();
}
static v8::Persistent<v8::FunctionTemplate> client_constructor_template;
static v8::Persistent<v8::FunctionTemplate> server_constructor_template;
- virtual size_t size (void) { return sizeof(HTTPConnection); };
-
protected:
static v8::Handle<v8::Value> NewClient (const v8::Arguments& args);
static v8::Handle<v8::Value> NewServer (const v8::Arguments& args);
- HTTPConnection (v8::Handle<v8::Object> handle,
- enum http_parser_type type);
+ HTTPConnection (enum http_parser_type type)
+ : Connection()
+ {
+ http_parser_init (&parser_, type);
+ parser_.on_message_begin = on_message_begin;
+ parser_.on_uri = on_uri;
+ parser_.on_header_field = on_header_field;
+ parser_.on_header_value = on_header_value;
+ parser_.on_headers_complete = on_headers_complete;
+ parser_.on_body = on_body;
+ parser_.on_message_complete = on_message_complete;
+ parser_.data = this;
+ }
void OnReceive (const void *buf, size_t len);
static void Initialize (v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template;
- virtual size_t size (void) { return sizeof(HTTPServer); };
-
protected:
static v8::Handle<v8::Value> New (const v8::Arguments& args);
- HTTPServer (v8::Handle<v8::Object> handle) : Server(handle) {}
+ HTTPServer (void) : Server() {}
v8::Handle<v8::FunctionTemplate> GetConnectionTemplate (void);
Connection* UnwrapConnection (v8::Local<v8::Object> connection);
return ThrowException(String::New("This shouldn't happen."));
}
-Connection::Connection (Handle<Object> handle)
- : EventEmitter(handle)
-{
- encoding_ = RAW;
-
- host_ = NULL;
- port_ = NULL;
-
- Init();
-}
-
void
Connection::Init (void)
{
socket_.data = this;
}
-
Connection::~Connection ()
{
static int i = 0;
{
HandleScope scope;
- Connection *c = new Connection(args.This());
- ObjectWrap::InformV8ofAllocation(c);
+ Connection *connection = new Connection();
+ connection->Wrap(args.This());
return args.This();
}
target->Set(String::NewSymbol("Server"), constructor_template->GetFunction());
}
-Server::Server (Handle<Object> handle)
- : EventEmitter(handle)
-{
- HandleScope scope;
-
-#if 0
- // TODO SetOptions
- handle_->SetHiddenValue(CONNECTION_HANDLER_SYMBOL, connection_handler);
-
- int backlog = 1024; // default value
- Local<Value> backlog_v = options->Get(String::NewSymbol("backlog"));
- if (backlog_v->IsInt32()) {
- backlog = backlog_v->IntegerValue();
- }
-#endif
-
- oi_server_init(&server_, 1024);
- server_.on_connection = Server::on_connection;
- server_.data = this;
-}
static Local<String>
GetAddressString (struct sockaddr *addr)
{
HandleScope scope;
- Server *a = new Server(args.This());
- ObjectWrap::InformV8ofAllocation(a);
+ Server *server = new Server();
+ server->Wrap(args.This());
return args.This();
}
public:
static void Initialize (v8::Handle<v8::Object> target);
- virtual size_t size (void) { return sizeof(Connection); };
-
protected:
/* v8 interface */
static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> ReadyStateGetter (v8::Local<v8::String> _,
const v8::AccessorInfo& info);
- Connection (v8::Handle<v8::Object> handle);
- virtual ~Connection ();
+ Connection (void) : EventEmitter()
+ {
+ encoding_ = RAW;
+
+ host_ = NULL;
+ port_ = NULL;
+
+ Init();
+ }
+ virtual ~Connection (void);
int Connect (struct addrinfo *address) {
return oi_socket_connect (&socket_, address);
public:
static void Initialize (v8::Handle<v8::Object> target);
- virtual size_t size (void) { return sizeof(Server); };
-
protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> New (const v8::Arguments& args);
static v8::Handle<v8::Value> Listen (const v8::Arguments& args);
static v8::Handle<v8::Value> Close (const v8::Arguments& args);
- Server (v8::Handle<v8::Object> handle);
+ Server (void) : EventEmitter()
+ {
+ oi_server_init(&server_, 1024);
+ server_.on_connection = Server::on_connection;
+ server_.data = this;
+ }
virtual ~Server () { Close(); }
int Listen (struct addrinfo *address) {
using namespace node;
using namespace std;
-ObjectWrap::~ObjectWrap ( )
-{
- handle_->SetInternalField(0, Undefined());
- handle_.Dispose();
- handle_.Clear();
-}
-
-ObjectWrap::ObjectWrap (Handle<Object> handle)
-{
- // TODO throw exception if it's already set
- HandleScope scope;
- handle_ = Persistent<Object>::New(handle);
-
- Handle<External> external = External::New(this);
- handle_->SetInternalField(0, external);
- handle_.MakeWeak(this, ObjectWrap::MakeWeak);
-
- attach_count_ = 0;
- weak_ = false;
-}
-
-void
-ObjectWrap::Attach ()
-{
- attach_count_ += 1;
-}
-
-void
-ObjectWrap::Detach ()
-{
- if (attach_count_ > 0) attach_count_ -= 1;
-
- if (weak_ && attach_count_ == 0) {
- V8::AdjustAmountOfExternalAllocatedMemory(-size());
- delete this;
- }
-}
-
-void*
-ObjectWrap::Unwrap (Handle<Object> handle)
-{
- HandleScope scope;
- if (handle.IsEmpty()) {
- fprintf(stderr, "Node: Tried to unwrap empty object.\n");
- return NULL;
- }
- if ( handle->InternalFieldCount() == 0) {
- fprintf(stderr, "Node: Tried to unwrap object without internal fields.\n");
- return NULL;
- }
- Local<Value> value = handle->GetInternalField(0);
- if (value.IsEmpty()) {
- fprintf(stderr, "Tried to unwrap object with empty internal field.\n");
- return NULL;
- }
- Handle<External> field = Handle<External>::Cast(value);
- return field->Value();
-}
-
-void
-ObjectWrap::MakeWeak (Persistent<Value> value, void *data)
-{
- ObjectWrap *obj = static_cast<ObjectWrap*> (data);
-
- assert(value == obj->handle_);
-
- obj->weak_ = true;
- if (obj->attach_count_ == 0)
- delete obj;
-}
-
-void
-ObjectWrap::InformV8ofAllocation (ObjectWrap *obj)
-{
- v8::V8::AdjustAmountOfExternalAllocatedMemory(obj->size());
-}
-
static void
buf_free (oi_buf *b)
{
#include <v8.h>
#include <oi_socket.h>
-namespace node {
+#include "object_wrap.h"
-#define NODE_UNWRAP(type, value) static_cast<type*>(node::ObjectWrap::Unwrap(value))
+namespace node {
#define NODE_DEFINE_CONSTANT(target, constant) \
(target)->Set(v8::String::NewSymbol(#constant), \
void FatalException (v8::TryCatch &try_catch);
oi_buf * buf_new (size_t size);
-class ObjectWrap {
-public:
- ObjectWrap (v8::Handle<v8::Object> handle);
- virtual ~ObjectWrap ( );
-
- virtual size_t size (void) = 0;
-
- /* This must be called after each new ObjectWrap creation! */
- static void InformV8ofAllocation (node::ObjectWrap *obj);
-
-protected:
- static void* Unwrap (v8::Handle<v8::Object> handle);
-
- /* Attach() marks the object as being attached to an event loop.
- * Attached objects will not be garbage collected, even if
- * all references are lost.
- */
- void Attach();
-
- /* Detach() marks an object as detached from the event loop. This is its
- * default state. When an object with a "weak" reference changes from
- * attached to detached state it will be freed. Be careful not to access
- * the object after making this call as it might be gone!
- * (A "weak reference" is v8 terminology for an object that only has a
- * persistant handle.)
- */
- void Detach();
- v8::Persistent<v8::Object> handle_;
-
-private:
- static void MakeWeak (v8::Persistent<v8::Value> _, void *data);
- int attach_count_;
- bool weak_;
-};
-
} // namespace node
#endif // node_h
--- /dev/null
+#ifndef object_wrap_h
+#define object_wrap_h
+
+#include <v8.h>
+#include <assert.h>
+
+namespace node {
+
+#define NODE_UNWRAP(type, value) static_cast<type*>(node::ObjectWrap::Unwrap(value))
+
+class ObjectWrap {
+public:
+ ObjectWrap ( ) {
+ weak_ = false;
+ attached_ = false;
+ }
+
+ virtual ~ObjectWrap ( ) {
+ if (!handle_.IsEmpty()) {
+ handle_->SetInternalField(0, v8::Undefined());
+ handle_.Dispose();
+ handle_.Clear();
+ }
+ }
+
+ protected:
+ static inline void* Unwrap (v8::Handle<v8::Object> handle)
+ {
+ assert(!handle.IsEmpty());
+ assert(handle->InternalFieldCount() == 1);
+ return v8::Handle<v8::External>::Cast(
+ handle->GetInternalField(0))->Value();
+ }
+
+ inline void Wrap(v8::Handle<v8::Object> handle)
+ {
+ assert(handle_.IsEmpty());
+ assert(handle->InternalFieldCount() > 0);
+ handle_ = v8::Persistent<v8::Object>::New(handle);
+ handle_->SetInternalField(0, v8::External::New(this));
+ handle_.MakeWeak(this, MakeWeak);
+ }
+
+ /* Attach() marks the object as being attached to an event loop.
+ * Attached objects will not be garbage collected, even if
+ * all references are lost.
+ */
+ void Attach() {
+ assert(!handle_.IsEmpty());
+ attached_ = true;
+ }
+
+ /* Detach() marks an object as detached from the event loop. This is its
+ * default state. When an object with a "weak" reference changes from
+ * attached to detached state it will be freed. Be careful not to access
+ * the object after making this call as it might be gone!
+ * (A "weak reference" is v8 terminology for an object that only has a
+ * persistant handle.)
+ */
+ void Detach() {
+ assert(!handle_.IsEmpty());
+ attached_ = false;
+ if (weak_) delete this;
+ }
+
+ v8::Persistent<v8::Object> handle_;
+
+ private:
+ static void MakeWeak (v8::Persistent<v8::Value> value, void *data) {
+ ObjectWrap *obj = static_cast<ObjectWrap*>(data);
+ assert(value == obj->handle_);
+ obj->weak_ = true;
+ if (!obj->attached_) delete obj;
+ }
+ bool attached_;
+ bool weak_;
+};
+
+} // namespace node
+#endif // object_wrap_h
{
HandleScope scope;
- Process *p = new Process(args.Holder());
- ObjectWrap::InformV8ofAllocation(p);
+ Process *p = new Process();
+ p->Wrap(args.Holder());
return args.This();
}
return process->Close() == 0 ? True() : False();
}
-Process::Process (Handle<Object> handle)
- : EventEmitter(handle)
+Process::Process ()
+ : EventEmitter()
{
ev_init(&stdout_watcher_, Process::OnOutput);
stdout_watcher_.data = this;
class Process : EventEmitter {
public:
static void Initialize (v8::Handle<v8::Object> target);
- virtual size_t size (void) { return sizeof(Process); }
protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template;
static v8::Handle<v8::Value> Kill (const v8::Arguments& args);
static v8::Handle<v8::Value> PIDGetter (v8::Local<v8::String> _, const v8::AccessorInfo& info);
- Process(v8::Handle<v8::Object> handle);
+ Process();
~Process();
int Spawn (const char *command);
{
HandleScope scope;
- Timer *t = new Timer(args.Holder());
- ObjectWrap::InformV8ofAllocation(t);
+ Timer *t = new Timer();
+ t->Wrap(args.Holder());
return args.This();
}
public:
static void Initialize (v8::Handle<v8::Object> target);
- virtual size_t size (void) { return sizeof(Timer); }
-
protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template;
- Timer (v8::Handle<v8::Object> handle) : EventEmitter (handle) { }
+ Timer () : EventEmitter () { }
~Timer();
static v8::Handle<v8::Value> New (const v8::Arguments& args);