mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-19 12:06:36 +00:00
added commonjs 'require' implementation to v8
This commit is contained in:
@@ -3,4 +3,4 @@ NAME='v8'
|
||||
CFLAGS = ['-Wno-deprecated-declarations']
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lv8']
|
||||
GCC_LIST = ['plugin', 'v8_uwsgi.cc']
|
||||
GCC_LIST = ['plugin', 'v8_uwsgi.cc', 'v8_commonjs.cc']
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "v8_uwsgi.h"
|
||||
|
||||
extern struct uwsgi_v8 uv8;
|
||||
|
||||
static v8::Handle<v8::Value> uwsgi_v8_commonjs_require_do(char *filename) {
|
||||
|
||||
size_t len = 0;
|
||||
char *code = uwsgi_open_and_read(filename, &len, 1, NULL);
|
||||
|
||||
// we re-create every time an "exports" object to emulate a local object
|
||||
v8::Local<v8::Object> exports = v8::Object::New();
|
||||
v8::Context::GetCurrent()->Global()->Set(v8::String::New("exports"), exports);
|
||||
|
||||
// we do not use TryCatch as we directly use stderr and simply exit with error code 1
|
||||
v8::Handle<v8::Script> script = v8::Script::Compile( v8::String::New(code), v8::String::New(filename) );
|
||||
free(code);
|
||||
if (script.IsEmpty()) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> result = script->Run();
|
||||
if (result.IsEmpty()) {
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
static v8::Handle<v8::Value> uwsgi_v8_commonjs_require(const v8::Arguments& args) {
|
||||
if (args.Length() > 0) {
|
||||
v8::String::Utf8Value module_name(args[0]->ToString());
|
||||
// ok lets start searching the module
|
||||
if (uwsgi_is_file(*module_name)) {
|
||||
return uwsgi_v8_commonjs_require_do(*module_name);
|
||||
}
|
||||
|
||||
// try appending .js extension
|
||||
if (!uwsgi_endswith(*module_name, (char *)".js")) {
|
||||
char *tmp_filename = uwsgi_concat2(*module_name, (char *)".js");
|
||||
if (uwsgi_is_file(tmp_filename)) {
|
||||
v8::Handle<v8::Value> ret = uwsgi_v8_commonjs_require_do(tmp_filename);
|
||||
free(tmp_filename);
|
||||
return ret;
|
||||
}
|
||||
free(tmp_filename);
|
||||
}
|
||||
|
||||
// let's start searching in the modules search path
|
||||
struct uwsgi_string_list *usl = uv8.module_paths;
|
||||
while(usl) {
|
||||
char *tmp_filename = uwsgi_concat3(usl->value, (char *)"/", *module_name);
|
||||
if (uwsgi_is_file(tmp_filename)) {
|
||||
v8::Handle<v8::Value> ret = uwsgi_v8_commonjs_require_do(tmp_filename);
|
||||
free(tmp_filename);
|
||||
return ret;
|
||||
}
|
||||
free(tmp_filename);
|
||||
if (!uwsgi_endswith(*module_name, (char *)".js")) {
|
||||
tmp_filename = uwsgi_concat4(usl->value, (char *)"/", *module_name, (char *)".js");
|
||||
if (uwsgi_is_file(tmp_filename)) {
|
||||
v8::Handle<v8::Value> ret = uwsgi_v8_commonjs_require_do(tmp_filename);
|
||||
free(tmp_filename);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
free(tmp_filename);
|
||||
usl = usl->next;
|
||||
}
|
||||
}
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
void uwsgi_v8_add_commonjs(v8::Handle<v8::ObjectTemplate> global) {
|
||||
global->Set(v8::String::New("require"), v8::FunctionTemplate::New(uwsgi_v8_commonjs_require));
|
||||
}
|
||||
+6
-24
@@ -1,28 +1,6 @@
|
||||
#include <uwsgi.h>
|
||||
#include <v8.h>
|
||||
#include "v8_uwsgi.h"
|
||||
|
||||
// as we have isolates in multithread modes, we need to maintain
|
||||
// special tables for the handlers (mules and spooler just run on the core 0)
|
||||
struct uwsgi_v8_signal_table {
|
||||
v8::Persistent<v8::Function> *func;
|
||||
uint8_t registered;
|
||||
};
|
||||
|
||||
struct uwsgi_v8_rpc_table {
|
||||
char *name;
|
||||
v8::Persistent<v8::Function> *func;
|
||||
};
|
||||
|
||||
struct uwsgi_v8 {
|
||||
v8::Persistent<v8::Context> *contexts;
|
||||
v8::Isolate **isolates;
|
||||
struct uwsgi_string_list *load;
|
||||
struct uwsgi_v8_signal_table *sigtable;
|
||||
struct uwsgi_v8_rpc_table *rpctable;
|
||||
pthread_key_t current_core;
|
||||
int preemptive;
|
||||
uint64_t gc_freq;
|
||||
} uv8;
|
||||
struct uwsgi_v8 uv8;
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_plugin v8_plugin;
|
||||
@@ -31,6 +9,7 @@ struct uwsgi_option uwsgi_v8_options[] = {
|
||||
{(char *)"v8-load", required_argument, 0, (char *)"load a javascript file", uwsgi_opt_add_string_list, &uv8.load, 0},
|
||||
{(char *)"v8-preemptive", required_argument, 0, (char *)"put v8 in preemptive move (single isolate) with the specified frequency", uwsgi_opt_set_int, &uv8.preemptive, 0},
|
||||
{(char *)"v8-gc-freq", required_argument, 0, (char *)"set the v8 garbage collection frequency", uwsgi_opt_set_64bit, &uv8.gc_freq, 0},
|
||||
{(char *)"v8-module-path", required_argument, 0, (char *)"set the v8 modules search path", uwsgi_opt_add_string_list, &uv8.module_paths, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
@@ -154,6 +133,7 @@ static v8::Handle<v8::Value> uwsgi_v8_api_log(const v8::Arguments& args) {
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
void uwsgi_v8_add_commonjs(v8::Handle<v8::ObjectTemplate>);
|
||||
|
||||
static v8::Persistent<v8::Context> uwsgi_v8_new_isolate(int core_id) {
|
||||
// create a new isolate
|
||||
@@ -174,6 +154,8 @@ static v8::Persistent<v8::Context> uwsgi_v8_new_isolate(int core_id) {
|
||||
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
|
||||
global->Set(v8::String::New("uwsgi"), uwsgi_api);
|
||||
|
||||
uwsgi_v8_add_commonjs(global);
|
||||
|
||||
// create a new context
|
||||
v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
|
||||
return context;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <uwsgi.h>
|
||||
#include <v8.h>
|
||||
|
||||
// as we have isolates in multithread modes, we need to maintain
|
||||
// special tables for the handlers (mules and spooler just run on the core 0)
|
||||
struct uwsgi_v8_signal_table {
|
||||
v8::Persistent<v8::Function> *func;
|
||||
uint8_t registered;
|
||||
};
|
||||
|
||||
struct uwsgi_v8_rpc_table {
|
||||
char *name;
|
||||
v8::Persistent<v8::Function> *func;
|
||||
};
|
||||
|
||||
struct uwsgi_v8 {
|
||||
v8::Persistent<v8::Context> *contexts;
|
||||
v8::Isolate **isolates;
|
||||
struct uwsgi_string_list *load;
|
||||
struct uwsgi_v8_signal_table *sigtable;
|
||||
struct uwsgi_v8_rpc_table *rpctable;
|
||||
pthread_key_t current_core;
|
||||
int preemptive;
|
||||
uint64_t gc_freq;
|
||||
struct uwsgi_string_list *module_paths;
|
||||
};
|
||||
Reference in New Issue
Block a user