Permalink
Browse files

Refactor to use candor objects and not use CWrapper based C++ classes

  • Loading branch information...
1 parent b48be54 commit 188de0c7f5f80c12579fb454351cc5afb40e632f @creationix creationix committed Mar 21, 2012
Showing with 567 additions and 654 deletions.
  1. +2 −0 Makefile
  2. +18 −25 src/cio.cc
  3. +2 −2 src/cio.h
  4. +14 −12 src/cio_string.cc
  5. +2 −2 src/cio_string.h
  6. +89 −79 src/lhttp_parser.cc
  7. +2 −21 src/lhttp_parser.h
  8. +7 −4 src/luv.cc
  9. +2 −27 src/luv.h
  10. +35 −0 src/luv_handle.cc
  11. +8 −0 src/luv_handle.h
  12. +182 −0 src/luv_stream.cc
  13. +8 −0 src/luv_stream.h
  14. +90 −287 src/luv_tcp.cc
  15. +3 −44 src/luv_tcp.h
  16. +77 −95 src/luv_timer.cc
  17. +3 −26 src/luv_timer.h
  18. +1 −13 src/main.cc
  19. +11 −9 test-tcp.can
  20. +11 −8 test-timer.can
View
@@ -16,6 +16,8 @@ LIBS=build/main.o \
build/cio_string.o \
build/luv.o \
build/luv_misc.o \
+ build/luv_handle.o \
+ build/luv_stream.o \
build/luv_tcp.o \
build/luv_timer.o
View
@@ -1,5 +1,14 @@
#include "cio.h"
#include "candor.h"
+
+// Modules
+#include "cio_string.h"
+#include "lhttp_parser.h"
+#include "luv.h"
+#include "luv_tcp.h"
+#include "luv_timer.h"
+
+
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
@@ -9,9 +18,6 @@
using namespace candor;
-static Object* builtins;
-static Object* builtinCache;
-
// Print a value to a fd
static void printValue(FILE* fd, Value* value, bool shallow) {
if (value->Is<String>()) {
@@ -134,32 +140,19 @@ static Value* Exit(uint32_t argc, Arguments& argv) {
}
static Value* LoadBuiltin(uint32_t argc, Arguments& argv) {
- assert(argc == 1 && argv[0]->Is<String>());
- String* name = argv[0]->As<String>();
- Value* cache = builtinCache->Get(name);
- if (!cache->Is<Nil>()) {
- return cache;
- }
- Value* obj = builtins->Get(name);
- assert(obj->Is<Function>());
- Function* setup = obj->As<Function>();
- Value* module = setup->Call(0, NULL);
- if (!module->Is<Nil>()) {
- builtinCache->Set(name, module);
- }
- return module;
+ assert(argc == 1);
+ const char* name = argv[0]->As<String>()->Value();
+ if (0 == strcmp(name, "string")) return cio_string_module();
+ if (0 == strcmp(name, "uv")) return uv_base_module();
+ if (0 == strcmp(name, "timer")) return uv_timer_module();
+ if (0 == strcmp(name, "tcp")) return uv_tcp_module();
+ if (0 == strcmp(name, "http_parser")) return http_parser_module();
+ return Nil::New();
}
-Object* cio_init(Object* global) {
+void cio_init(Object* global) {
global->Set("print", Function::New(Print));
global->Set("prettyPrint", Function::New(PrettyPrint));
global->Set("exit", Function::New(Exit));
global->Set("require", Function::New(LoadBuiltin));
- builtins = Object::New();
- builtinCache = Object::New();
- // Make the objects persistent
- new Handle<Object>(builtins);
- new Handle<Object>(builtinCache);
-
- return builtins;
}
View
@@ -5,6 +5,6 @@
using namespace candor;
-Object* cio_init(Object* global);
+void cio_init(Object* global);
-#endif
+#endif
View
@@ -67,18 +67,20 @@ static Value* readInt64(uint32_t argc, Arguments& argv) {
return Number::NewIntegral(*(int64_t*)((uint8_t*)str->Value() + offset));
}
-
-Value* cio_string_module(uint32_t argc, Arguments& argv) {
- Object* string = Object::New();
+static Object* module;
+Object* cio_string_module() {
+ if (module) return module;
+ module = Object::New();
+ new Handle<Object>(module);
// These match the endianess of the host.
// TODO: add functions using explicit endianess
- string->Set("readUInt8", Function::New(readUInt8));
- string->Set("readInt8", Function::New(readInt8));
- string->Set("readUInt16", Function::New(readUInt16));
- string->Set("readInt16", Function::New(readInt16));
- string->Set("readUInt32", Function::New(readUInt32));
- string->Set("readInt32", Function::New(readInt32));
- string->Set("readUInt64", Function::New(readUInt64));
- string->Set("readInt64", Function::New(readInt64));
- return string;
+ module->Set("readUInt8", Function::New(readUInt8));
+ module->Set("readInt8", Function::New(readInt8));
+ module->Set("readUInt16", Function::New(readUInt16));
+ module->Set("readInt16", Function::New(readInt16));
+ module->Set("readUInt32", Function::New(readUInt32));
+ module->Set("readInt32", Function::New(readInt32));
+ module->Set("readUInt64", Function::New(readUInt64));
+ module->Set("readInt64", Function::New(readInt64));
+ return module;
}
View
@@ -4,6 +4,6 @@
#include "candor.h"
using namespace candor;
-Value* cio_string_module(uint32_t argc, Arguments& argv);
+Object* cio_string_module();
-#endif
+#endif
View
@@ -6,51 +6,107 @@
#include <stdio.h>
using namespace candor;
-using namespace candorIO;
static http_parser_settings settings;
+static int emit(http_parser* parser, const char* name) {
+ Object* obj = (Object*)parser->data;
+ Value* callback = obj->Get(name);
+ if (callback->Is<Function>()) {
+ Value* result = callback->As<Function>()->Call(0, NULL);
+ return result->ToNumber()->IntegralValue();
+ }
+ return 0;
+}
+
+static int emit(http_parser* parser, const char* name, const char *at, size_t length) {
+ Object* obj = (Object*)parser->data;
+ Value* callback = obj->Get(name);
+ if (callback->Is<Function>()) {
+ Value* argv[1];
+ argv[0] = String::New(at, length);
+ Value* result = callback->As<Function>()->Call(1, argv);
+ return result->ToNumber()->IntegralValue();
+ }
+ return 0;
+}
+
static int lhttp_on_message_begin(http_parser* parser) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("messageBegin");
+ return emit(parser, "onMessageBegin");
}
static int lhttp_on_url(http_parser* parser, const char *at, size_t length) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("url", at, length);
+ return emit(parser, "onUrl", at, length);
}
static int lhttp_on_header_field(http_parser* parser, const char *at, size_t length) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("headerField", at, length);
+ return emit(parser, "onHeaderField", at, length);
}
static int lhttp_on_header_value(http_parser* parser, const char *at, size_t length) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("headerValue", at, length);
+ return emit(parser, "onHeaderValue", at, length);
}
static int lhttp_on_headers_complete(http_parser* parser) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("headersComplete");
+ return emit(parser, "onHeadersComplete");
}
static int lhttp_on_body(http_parser* parser, const char *at, size_t length) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("body", at, length);
+ return emit(parser, "onBody", at, length);
}
static int lhttp_on_message_complete(http_parser* parser) {
- return (reinterpret_cast<HttpParser*>(parser->data))->Emit("messageComplete");
+ return emit(parser, "onMessageComplete");
}
static Value* lhttp_create(uint32_t argc, Arguments& argv) {
- HttpParser* parser = new HttpParser();
- return parser->Wrap();
+ assert(argc == 0);
+ Object* obj = Object::New();
+ CData* cdata = CData::New(sizeof(http_parser));
+ http_parser* parser = (http_parser*)cdata->GetContents();
+ parser->data = obj;
+ obj->Set("cdata", cdata);
+ return obj;
}
+
static Value* lhttp_init(uint32_t argc, Arguments& argv) {
- assert(argc && argv[0]->Is<CData>());
- return CWrapper::Unwrap<HttpParser>(argv[0])->Init(argc, argv);
+ assert(argc >= 2 && argc <= 3);
+ Object* obj = argv[0]->As<Object>();
+ http_parser* parser = (http_parser*)obj->Get("cdata")->As<CData>()->GetContents();
+ const char* type = argv[1]->As<String>()->Value();
+ if (argc == 3) {
+ Object* callbacks = argv[2]->As<Object>();
+ Array* keys = callbacks->Keys();
+ int64_t i = keys->Length();
+ while (i--) {
+ Value* key = keys->Get(i);
+ obj->Set(key, callbacks->Get(key));
+ }
+ }
+ if (0 == strcmp(type, "request")) {
+ http_parser_init(parser, HTTP_REQUEST);
+ } else if (0 == strcmp(type, "response")) {
+ http_parser_init(parser, HTTP_RESPONSE);
+ } else if (0 == strcmp(type, "both")) {
+ http_parser_init(parser, HTTP_BOTH);
+ } else {
+ assert(false);
+ }
+ return Nil::New();
}
+
static Value* lhttp_execute(uint32_t argc, Arguments& argv) {
- assert(argc && argv[0]->Is<CData>());
- return CWrapper::Unwrap<HttpParser>(argv[0])->Execute(argc, argv);
-}
-static Value* lhttp_finish(uint32_t argc, Arguments& argv) {
- assert(argc && argv[0]->Is<CData>());
- return CWrapper::Unwrap<HttpParser>(argv[0])->Finish(argc, argv);
+ assert(argc == 2);
+ Object* obj = argv[0]->As<Object>();
+ http_parser* parser = (http_parser*)obj->Get("cdata")->As<CData>()->GetContents();
+ String* str = argv[1]->As<String>();
+ const char* data = str->Value();
+ size_t len = str->Length();
+ size_t nparsed = http_parser_execute(parser, &settings, data, len);
+ return Number::NewIntegral(nparsed);
}
+
static Value* lhttp_pause(uint32_t argc, Arguments& argv) {
- assert(argc && argv[0]->Is<CData>());
- return CWrapper::Unwrap<HttpParser>(argv[0])->Pause(argc, argv);
+ assert(argc == 2);
+ Object* obj = argv[0]->As<Object>();
+ http_parser* parser = (http_parser*)obj->Get("cdata")->As<CData>()->GetContents();
+ int paused = argv[1]->As<Boolean>()->IsTrue();
+ http_parser_pause(parser, paused);
+ return Nil::New();
}
static Value* lhttp_parse_url(uint32_t argc, Arguments& argv) {
@@ -92,7 +148,9 @@ static Value* lhttp_parse_url(uint32_t argc, Arguments& argv) {
return url;
}
-Value* http_parser_module(uint32_t argc, Arguments& argv) {
+static Object* module;
+Object* http_parser_module() {
+ if (module) return module;
// Initialize the settings
settings.on_message_begin = lhttp_on_message_begin;
settings.on_url = lhttp_on_url;
@@ -102,71 +160,23 @@ Value* http_parser_module(uint32_t argc, Arguments& argv) {
settings.on_body = lhttp_on_body;
settings.on_message_complete = lhttp_on_message_complete;
- Object* module = Object::New();
+ module = Object::New();
module->Set("parseUrl", Function::New(lhttp_parse_url));
module->Set("create", Function::New(lhttp_create));
- module->Set("init", Function::New(lhttp_init));
- module->Set("execute", Function::New(lhttp_execute));
- module->Set("finish", Function::New(lhttp_finish));
- module->Set("pause", Function::New(lhttp_pause));
return module;
}
-
-int HttpParser::Emit(const char* name) {
- Value* callback = callbacks->Get(name);
- if (callback->Is<Function>()) {
- Value* result = callback->As<Function>()->Call(0, NULL);
- return result->ToNumber()->IntegralValue();
- }
- return 0;
-}
-
-int HttpParser::Emit(const char* name, const char *at, size_t length) {
- Value* callback = callbacks->Get(name);
- if (callback->Is<Function>()) {
- Value* argv[1];
- argv[0] = String::New(at, length);
- Value* result = callback->As<Function>()->Call(1, argv);
- return result->ToNumber()->IntegralValue();
- }
- return 0;
-}
-
-Value* HttpParser::Init(uint32_t argc, Arguments& argv) {
- assert(argc == 3 && argv[1]->Is<String>() && argv[2]->Is<Object>());
- const char* type = argv[1]->As<String>()->Value();
- callbacks.Wrap(argv[2]->As<Object>());
- if (0 == strcmp(type, "request")) {
- http_parser_init(&parser, HTTP_REQUEST);
- } else if (0 == strcmp(type, "response")) {
- http_parser_init(&parser, HTTP_RESPONSE);
- } else if (0 == strcmp(type, "both")) {
- http_parser_init(&parser, HTTP_BOTH);
- } else {
- return String::New("type must be 'request' or 'response' or 'both'");
- }
- return Nil::New();
+static Object* prototype;
+Object* http_parser_prototype() {
+ if (prototype) return prototype;
+ prototype = Object::New();
+ new Handle<Object>(prototype);
+ prototype->Set("init", Function::New(lhttp_init));
+ prototype->Set("execute", Function::New(lhttp_execute));
+ prototype->Set("pause", Function::New(lhttp_pause));
+ return prototype;
}
-Value* HttpParser::Execute(uint32_t argc, Arguments& argv) {
- assert(argc == 2 && argv[1]->Is<String>());
- String* str = argv[1]->As<String>();
- const char* data = str->Value();
- size_t len = str->Length();
- size_t nparsed = http_parser_execute(&parser, &settings, data, len);
- return Number::NewIntegral(nparsed);
-}
-Value* HttpParser::Pause(uint32_t argc, Arguments& argv) {
- assert(argc = 2 && argv[1]->Is<Boolean>());
- int paused = argv[1]->As<Boolean>()->IsTrue();
- http_parser_pause(&parser, paused);
- return Nil::New();
-}
-Value* HttpParser::Finish(uint32_t argc, Arguments& argv) {
- printf("TODO: Implement HttpParser::Finish\n");
- return Nil::New();
-}
View
@@ -2,27 +2,8 @@
#define LHTTP_PARSER_H
#include "candor.h"
-#include "http_parser.h"
-using namespace candor;
-
-namespace candorIO {
-
- class HttpParser : public CWrapper {
- http_parser parser;
- Handle<Object> callbacks;
- public:
-
- int Emit(const char* name);
- int Emit(const char* name, const char *at, size_t length);
- Value* Init(uint32_t argc, Arguments& argv);
- Value* Execute(uint32_t argc, Arguments& argv);
- Value* Finish(uint32_t argc, Arguments& argv);
- Value* Pause(uint32_t argc, Arguments& argv);
- };
-}
-
-
-Value* http_parser_module(uint32_t argc, Arguments& argv);
+candor::Object* http_parser_module();
+candor::Object* http_parser_prototype();
#endif
View
@@ -14,8 +14,11 @@ static Value* luv_last_error(uint32_t argc, Arguments& argv) {
return error;
}
-Value* uv_base_module(uint32_t argc, Arguments& argv) {
- Object* uv = Object::New();
- uv->Set("lastError", Function::New(luv_last_error));
- return uv;
+static Object* module;
+Object* uv_base_module() {
+ if (module) return module;
+ module = Object::New();
+ new Handle<Object>(module);
+ module->Set("lastError", Function::New(luv_last_error));
+ return module;
}
Oops, something went wrong.

0 comments on commit 188de0c

Please sign in to comment.