#include #include #include #include #include #include #include #include using namespace v8; class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { void* data = AllocateUninitialized(length); return data == NULL ? data : memset(data, 0, length); } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } virtual void Free(void* data, size_t) { free(data); } }; typedef struct { Isolate* isolate; Persistent* context; ArrayBufferAllocator* allocator; } ContextInfo; typedef struct { bool parsed; bool executed; bool terminated; Persistent* value; Persistent* message; Persistent* backtrace; } EvalResult; typedef struct { ContextInfo* context_info; Local* eval; useconds_t timeout; EvalResult* result; } EvalParams; static VALUE rb_eScriptTerminatedError; static VALUE rb_eParseError; static VALUE rb_eScriptRuntimeError; static VALUE rb_cJavaScriptFunction; static Platform* current_platform = NULL; static void init_v8() { if (current_platform == NULL) { V8::InitializeICU(); current_platform = platform::CreateDefaultPlatform(); V8::InitializePlatform(current_platform); V8::Initialize(); } } void* breaker(void *d) { EvalParams* data = (EvalParams*)d; usleep(data->timeout*1000); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); V8::TerminateExecution(data->context_info->isolate); return NULL; } void* nogvl_context_eval(void* arg) { EvalParams* eval_params = (EvalParams*)arg; EvalResult* result = eval_params->result; Isolate* isolate = eval_params->context_info->isolate; Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); TryCatch trycatch(isolate); Local context = eval_params->context_info->context->Get(isolate); Context::Scope context_scope(context); MaybeLocal