diff --git a/Makefile b/Makefile index 5354585..aca7e64 100644 --- a/Makefile +++ b/Makefile @@ -20,13 +20,15 @@ DEPS=${CANDIR}/candor.a \ LIBS=build/main.o \ build/lhttp_parser.o \ build/cio.o \ + build/cio_libs.o \ build/cio_string.o \ build/luv.o \ build/luv_base.o \ build/luv_handle.o \ build/luv_stream.o \ build/luv_tcp.o \ - build/luv_timer.o + build/luv_timer.o \ + build/net.o all: build/canio @@ -39,10 +41,12 @@ ${UVDIR}/uv.a: ${UVDIR}/Makefile ${HTTPDIR}/http_parser.o: ${HTTPDIR}/Makefile $(MAKE) -C ${HTTPDIR} http_parser.o - build: mkdir -p build +build/%.o: lib/%.can build + objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $< $@ + build/%.o: src/%.cc build src/%.h ${DEPS} g++ -g -Wall -Werror -c $< -o $@ -I${HTTPDIR} -I${UVDIR}/include -I${CANDIR}/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 diff --git a/lib/net.can b/lib/net.can new file mode 100644 index 0000000..05e7d21 --- /dev/null +++ b/lib/net.can @@ -0,0 +1,81 @@ +require = global.require + +throw = (err) { + global.prettyPrint(err) + global.exit() +} + +// Used to emit on errors when libuv badness happens +check = (status) { + if (status) { + throw(require('uv').lastError()) + } +} + +Tcp = require('tcp') + +StreamPrototype = {} +StreamPrototype.pipe = (self, stream) { + self.onData = (chunk) { + stream:write(chunk) + } + self.onEnd = () { + stream:end() + } +} + +ClientPrototype = new StreamPrototype +ClientPrototype.write = (self, chunk, callback) { + check(self.socket:write(chunk, callback)) +} +ClientPrototype.end = (self) { + check(self.socket:shutdown((status) { + check(status) + self.socket:close() + })) +} + +ServerPrototype = {} +ServerPrototype.listen = (self, port, host, callback) { + if (!host) host = "0.0.0.0" + check(self.socket:bind(host, port)) + check(self.socket:listen(128, (status) { + check(status) + client = new ClientPrototype + socket = Tcp.create() + client.socket = socket + check(self.socket:accept(socket)) + self.onConnection(client) + check(socket:readStart((nread, chunk) { + if (nread == -1) { + err = require('uv').lastError() + if (err.name == "EOF") { + client.onEnd() + } else { + throw(err) + } + return + } + if (nread > 0) { + client.onData(chunk) + return + } + })) + })) +} + +createServer = function (onConnection) { + p("createServer", onConnection) + server = new ServerPrototype + socket = Tcp.create() + server.socket = socket + server.onConnection = onConnection + return server +} + +return { + StreamPrototype: StreamPrototype, + ClientPrototype: ClientPrototype, + ServerPrototype: ServerPrototype, + createServer: createServer +} diff --git a/net.can b/net.can index d84d705..5b1855b 100644 --- a/net.can +++ b/net.can @@ -1,84 +1,8 @@ print = global.print -p = global.prettyPrint -require = global.require - -throw = (err) { - p(err) - global.exit() -} - -// Used to emit on errors when libuv badness happens -check = (status) { - if (status) { - throw(require('uv').lastError()) - } -} - -Tcp = require('tcp') - -StreamPrototype = {} -StreamPrototype.pipe = (self, stream) { - self.onData = (chunk) { - stream:write(chunk) - } - self.onEnd = () { - stream:end() - } -} - -ClientPrototype = new StreamPrototype -ClientPrototype.write = (self, chunk, callback) { - check(self.socket:write(chunk, callback)) -} -ClientPrototype.end = (self) { - check(self.socket:shutdown((status) { - check(status) - self.socket:close() - })) -} - -ServerPrototype = {} -ServerPrototype.listen = (self, port, host, callback) { - if (!host) host = "0.0.0.0" - check(self.socket:bind(host, port)) - check(self.socket:listen(128, (status) { - check(status) - client = new ClientPrototype - socket = Tcp.create() - client.socket = socket - check(self.socket:accept(socket)) - self.onConnection(client) - check(socket:readStart((nread, chunk) { - if (nread == -1) { - err = require('uv').lastError() - if (err.name == "EOF") { - client.onEnd() - } else { - throw(err) - } - return - } - if (nread > 0) { - client.onData(chunk) - return - } - })) - })) -} - -createServer = function (onConnection) { - p("createServer", onConnection) - server = new ServerPrototype - socket = Tcp.create() - server.socket = socket - server.onConnection = onConnection - return server -} - -//////////////////////////////////////////////////////////////////////////////// +net = global.require('net') // Make an echo server using the API -server = createServer((client) { +server = net.createServer((client) { print("new client, piping data back to it") client:pipe(client) }):listen(8080) diff --git a/src/cio.cc b/src/cio.cc index eda30eb..87a4735 100644 --- a/src/cio.cc +++ b/src/cio.cc @@ -2,6 +2,7 @@ #include "candor.h" +#include "cio_libs.h" // cio_net_module #include "cio_string.h" // cio_string_module #include "lhttp_parser.h" // http_parser_module #include "luv_base.h" // uv_base_module @@ -148,6 +149,10 @@ static Value* Exit(uint32_t argc, Value* argv[]) { static Value* LoadBuiltin(uint32_t argc, Value* argv[]) { assert(argc == 1); const char* name = argv[0]->As()->Value(); +#define XX(Name) \ + if (0 == strcmp(name, #Name)) return cio_##Name##_module(); + CIO_LIB_MAP(XX) +#undef XX 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(); diff --git a/src/cio_libs.cc b/src/cio_libs.cc new file mode 100644 index 0000000..b6f4b25 --- /dev/null +++ b/src/cio_libs.cc @@ -0,0 +1,28 @@ +#include "cio_libs.h" + +#include "candor.h" + +#include + +using namespace candor; + + +#define XX(name) \ +extern char _binary_lib_##name##_can_start; \ +extern char _binary_lib_##name##_can_end; \ +static Handle module_##name; \ +Object* cio_##name##_module() { \ + if (!module_##name.IsEmpty()) { \ + return *module_##name; \ + } \ + char* code = &_binary_lib_##name##_can_start; \ + int len = &_binary_lib_##name##_can_end - \ + &_binary_lib_##name##_can_start; \ + Function* fn = Function::New(code, len); \ + module_##name.Wrap(fn->Call(0, NULL)); \ + return *module_##name; \ +} \ + +CIO_LIB_MAP(XX) +#undef XX + diff --git a/src/cio_libs.h b/src/cio_libs.h new file mode 100644 index 0000000..df91bd7 --- /dev/null +++ b/src/cio_libs.h @@ -0,0 +1,13 @@ +#ifndef CIO_LIBS_H +#define CIO_LIBS_H + +#include "candor.h" + +#define CIO_LIB_MAP(XX) \ + XX(net) + +#define XX(name) candor::Object* cio_##name##_module(); + CIO_LIB_MAP(XX) +#undef XX + +#endif