0
0
mirror of https://github.com/phpv8/v8js.git synced 2025-01-03 16:51:52 +00:00

Adapt to new v8::Persistent API, support V8 >= 3.21.12

This commit is contained in:
Stefan Siegl 2013-10-03 16:27:04 +02:00
parent 1c4d9817dc
commit 619231913c
5 changed files with 98 additions and 53 deletions

View File

@ -14,7 +14,7 @@ Minimum requirements
V8 is Google's open source Javascript engine. V8 is Google's open source Javascript engine.
V8 is written in C++ and is used in Google Chrome, the open source browser from Google. V8 is written in C++ and is used in Google Chrome, the open source browser from Google.
V8 implements ECMAScript as specified in ECMA-262, 5th edition. V8 implements ECMAScript as specified in ECMA-262, 5th edition.
This extension makes use of V8 isolates to ensure separation between multiple V8Js instances, hence the need for 3.17.11 or above. (See <https://github.com/preillyme/v8js/issues/12>.) This extension makes use of V8 isolates to ensure separation between multiple V8Js instances and already uses the new persistence API, hence the need for 3.21.12 or above.
- PHP 5.3.3+ - PHP 5.3.3+
@ -51,7 +51,7 @@ cd /tmp
git clone https://github.com/preillyme/v8js.git git clone https://github.com/preillyme/v8js.git
cd v8js cd v8js
phpize phpize
./configure CXXFLAGS="-DV8_USE_UNSAFE_HANDLES=1" ./configure
make make
sudo make install sudo make install
``` ```

View File

@ -67,9 +67,8 @@ CPPFLAGS=$old_CPPFLAGS
set $ac_cv_v8_version set $ac_cv_v8_version
IFS=$ac_IFS IFS=$ac_IFS
V8_API_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` V8_API_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3`
if test "$V8_API_VERSION" -lt 3017011 ; then if test "$V8_API_VERSION" -lt 3021012 ; then
# see https://github.com/preillyme/v8js/issues/12 AC_MSG_ERROR([libv8 must be version 3.21.12 or greater])
AC_MSG_ERROR([libv8 must be version 3.17.11 or greater])
fi fi
AC_DEFINE_UNQUOTED([PHP_V8_API_VERSION], $V8_API_VERSION, [ ]) AC_DEFINE_UNQUOTED([PHP_V8_API_VERSION], $V8_API_VERSION, [ ])
AC_DEFINE_UNQUOTED([PHP_V8_VERSION], "$ac_cv_v8_version", [ ]) AC_DEFINE_UNQUOTED([PHP_V8_VERSION], "$ac_cv_v8_version", [ ])

101
v8js.cc
View File

@ -116,15 +116,18 @@ static zval *php_v8js_v8_read_property(zval *object, zval *member, int type ZEND
zval *retval = NULL; zval *retval = NULL;
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC); php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
if (Z_TYPE_P(member) == IS_STRING && obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) v8::Locker locker(obj->isolate);
{ v8::Isolate::Scope isolate_scope(obj->isolate);
v8::Locker locker(obj->isolate); v8::HandleScope local_scope(obj->isolate);
v8::Isolate::Scope isolate_scope(obj->isolate); v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::HandleScope local_scope(obj->isolate); v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Object> jsObj = obj->v8obj->ToObject(); v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject() && !v8obj->IsFunction())
{
v8::Local<v8::Object> jsObj = v8obj->ToObject();
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), Z_STRLEN_P(member)); v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), Z_STRLEN_P(member));
v8::Local<v8::Value> jsVal; v8::Local<v8::Value> jsVal;
@ -155,8 +158,16 @@ static void php_v8js_v8_write_property(zval *object, zval *member, zval *value Z
{ {
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC); php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
if (obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) { v8::Locker locker(obj->isolate);
obj->v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, obj->isolate TSRMLS_CC)); v8::Isolate::Scope isolate_scope(obj->isolate);
v8::HandleScope local_scope(obj->isolate);
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (v8obj->IsObject() && !v8obj->IsFunction()) {
v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, obj->isolate TSRMLS_CC));
} }
} }
/* }}} */ /* }}} */
@ -165,8 +176,16 @@ static void php_v8js_v8_unset_property(zval *object, zval *member ZEND_HASH_KEY_
{ {
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC); php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
if (obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) { v8::Locker locker(obj->isolate);
obj->v8obj->ToObject()->ForceDelete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member))); v8::Isolate::Scope isolate_scope(obj->isolate);
v8::HandleScope local_scope(obj->isolate);
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (v8obj->IsObject() && !v8obj->IsFunction()) {
v8obj->ToObject()->ForceDelete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)));
} }
} }
/* }}} */ /* }}} */
@ -224,8 +243,9 @@ static HashTable *php_v8js_v8_get_properties(zval *object TSRMLS_DC) /* {{{ */
v8::HandleScope local_scope(obj->isolate); v8::HandleScope local_scope(obj->isolate);
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate); v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context); v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) { if (php_v8js_v8_get_properties_hash(v8obj, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) {
return retval; return retval;
} }
@ -251,9 +271,10 @@ static zend_function *php_v8js_v8_get_method(zval **object_ptr, char *method, in
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate); v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context); v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::String> jsKey = V8JS_STRL(method, method_len); v8::Local<v8::String> jsKey = V8JS_STRL(method, method_len);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (!obj->v8obj.IsEmpty() && obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) { if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction()) {
v8::Local<v8::Object> jsObj = obj->v8obj->ToObject(); v8::Local<v8::Object> jsObj = v8obj->ToObject();
if (jsObj->Has(jsKey) && jsObj->Get(jsKey)->IsFunction()) { if (jsObj->Has(jsKey) && jsObj->Get(jsKey)->IsFunction()) {
f = (zend_function *) ecalloc(1, sizeof(*f)); f = (zend_function *) ecalloc(1, sizeof(*f));
@ -296,7 +317,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
v8::Context::Scope temp_scope(temp_context); v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::String> method_name = V8JS_SYML(method, strlen(method)); v8::Local<v8::String> method_name = V8JS_SYML(method, strlen(method));
v8::Local<v8::Object> v8obj = obj->v8obj->ToObject(); v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj)->ToObject();
v8::Local<v8::Function> cb; v8::Local<v8::Function> cb;
if (method_name->Equals(V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME))) { if (method_name->Equals(V8JS_SYM(V8JS_V8_INVOKE_FUNC_NAME))) {
@ -309,7 +330,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
v8::Local<v8::Value> js_retval; v8::Local<v8::Value> js_retval;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
jsArgv[i] = v8::Local<v8::Value>::New(zval_to_v8js(*argv[i], obj->isolate TSRMLS_CC)); jsArgv[i] = v8::Local<v8::Value>::New(obj->isolate, zval_to_v8js(*argv[i], obj->isolate TSRMLS_CC));
} }
js_retval = cb->Call(V8JS_GLOBAL, argc, jsArgv); js_retval = cb->Call(V8JS_GLOBAL, argc, jsArgv);
@ -334,7 +355,14 @@ static int php_v8js_v8_get_closure(zval *object, zend_class_entry **ce_ptr, zend
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC); php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
if (!obj->v8obj->IsFunction()) { v8::Locker locker(obj->isolate);
v8::Isolate::Scope isolate_scope(obj->isolate);
v8::HandleScope local_scope(obj->isolate);
v8::Local<v8::Context> temp_context = v8::Context::New(obj->isolate);
v8::Context::Scope temp_scope(temp_context);
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(obj->isolate, obj->v8obj);
if (!v8obj->IsFunction()) {
return FAILURE; return FAILURE;
} }
@ -392,7 +420,7 @@ void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags, v8::I
c = (php_v8js_object *) zend_object_store_get_object(res TSRMLS_CC); c = (php_v8js_object *) zend_object_store_get_object(res TSRMLS_CC);
c->v8obj = v8::Persistent<v8::Value>::New(isolate, value); c->v8obj.Reset(isolate, value);
c->flags = flags; c->flags = flags;
c->isolate = isolate; c->isolate = isolate;
} }
@ -555,6 +583,7 @@ static PHP_METHOD(V8Js, __construct)
c->pending_exception = NULL; c->pending_exception = NULL;
c->in_execution = 0; c->in_execution = 0;
c->isolate = v8::Isolate::New(); c->isolate = v8::Isolate::New();
c->isolate->SetData(c);
c->time_limit_hit = false; c->time_limit_hit = false;
c->memory_limit_hit = false; c->memory_limit_hit = false;
c->module_loader = NULL; c->module_loader = NULL;
@ -590,15 +619,17 @@ static PHP_METHOD(V8Js, __construct)
/* Create global template for global object */ /* Create global template for global object */
// Now we are using multiple isolates this needs to be created for every context // Now we are using multiple isolates this needs to be created for every context
c->global_template = v8::Persistent<v8::FunctionTemplate>::New(c->isolate, v8::FunctionTemplate::New()); v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New();
c->global_template->SetClassName(V8JS_SYM("V8Js")); tpl->SetClassName(V8JS_SYM("V8Js"));
c->global_template.Reset(c->isolate, tpl);
/* Register builtin methods */ /* Register builtin methods */
php_v8js_register_methods(c->global_template->InstanceTemplate(), c); php_v8js_register_methods(tpl->InstanceTemplate(), c);
/* Create context */ /* Create context */
c->context = v8::Persistent<v8::Context>::New(c->isolate, v8::Context::New(c->isolate, &extension_conf, c->global_template->InstanceTemplate())); v8::Local<v8::Context> context = v8::Context::New(c->isolate, &extension_conf, tpl->InstanceTemplate());
c->context->SetAlignedPointerInEmbedderData(1, c); context->SetAlignedPointerInEmbedderData(1, c);
c->context.Reset(c->isolate, context);
if (exts) { if (exts) {
_php_v8js_free_ext_strarr(exts, exts_count); _php_v8js_free_ext_strarr(exts, exts_count);
@ -612,7 +643,7 @@ static PHP_METHOD(V8Js, __construct)
} }
/* Enter context */ /* Enter context */
v8::Context::Scope context_scope(c->context); v8::Context::Scope context_scope(context);
/* Create the PHP container object's function template */ /* Create the PHP container object's function template */
v8::Local<v8::FunctionTemplate> php_obj_t = v8::FunctionTemplate::New(); v8::Local<v8::FunctionTemplate> php_obj_t = v8::FunctionTemplate::New();
@ -635,10 +666,11 @@ static PHP_METHOD(V8Js, __construct)
} }
/* Set name for the PHP JS object */ /* Set name for the PHP JS object */
c->object_name = v8::Persistent<v8::String>::New(c->isolate, (object_name_len) ? V8JS_SYML(object_name, object_name_len) : V8JS_SYM("PHP")); v8::Local<v8::String> object_name_js = (object_name_len) ? V8JS_SYML(object_name, object_name_len) : V8JS_SYM("PHP");
c->object_name.Reset(c->isolate, object_name_js);
/* Add the PHP object into global object */ /* Add the PHP object into global object */
V8JS_GLOBAL->Set(c->object_name, php_obj_t->InstanceTemplate()->NewInstance(), v8::ReadOnly); V8JS_GLOBAL->Set(object_name_js, php_obj_t->InstanceTemplate()->NewInstance(), v8::ReadOnly);
} }
/* }}} */ /* }}} */
@ -653,7 +685,8 @@ static PHP_METHOD(V8Js, __construct)
(ctx) = (php_v8js_ctx *) zend_object_store_get_object(object TSRMLS_CC); \ (ctx) = (php_v8js_ctx *) zend_object_store_get_object(object TSRMLS_CC); \
v8::Locker locker((ctx)->isolate); \ v8::Locker locker((ctx)->isolate); \
v8::Isolate::Scope isolate_scope((ctx)->isolate); \ v8::Isolate::Scope isolate_scope((ctx)->isolate); \
v8::Context::Scope context_scope((ctx)->context); v8::HandleScope handle_scope((ctx)->isolate); \
v8::Context::Scope context_scope((ctx)->isolate, (ctx)->context);
static void php_v8js_timer_push(long time_limit, long memory_limit, php_v8js_ctx *c TSRMLS_DC) static void php_v8js_timer_push(long time_limit, long memory_limit, php_v8js_ctx *c TSRMLS_DC)
{ {
@ -762,8 +795,6 @@ static PHP_METHOD(V8Js, executeString)
/* Catch JS exceptions */ /* Catch JS exceptions */
v8::TryCatch try_catch; v8::TryCatch try_catch;
v8::HandleScope handle_scope(c->isolate);
/* Set script identifier */ /* Set script identifier */
v8::Local<v8::String> sname = identifier_len ? V8JS_SYML(identifier, identifier_len) : V8JS_SYM("V8Js::executeString()"); v8::Local<v8::String> sname = identifier_len ? V8JS_SYML(identifier, identifier_len) : V8JS_SYM("V8Js::executeString()");
@ -1089,10 +1120,9 @@ static void php_v8js_write_property(zval *object, zval *member, zval *value ZEND
{ {
V8JS_BEGIN_CTX(c, object) V8JS_BEGIN_CTX(c, object)
v8::HandleScope handle_scope(c->isolate);
/* Global PHP JS object */ /* Global PHP JS object */
v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(c->object_name)->ToObject(); v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(c->isolate, c->object_name);
v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(object_name_js)->ToObject();
/* Write value to PHP JS object */ /* Write value to PHP JS object */
jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, c->isolate TSRMLS_CC), v8::ReadOnly); jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, c->isolate TSRMLS_CC), v8::ReadOnly);
@ -1106,10 +1136,9 @@ static void php_v8js_unset_property(zval *object, zval *member ZEND_HASH_KEY_DC
{ {
V8JS_BEGIN_CTX(c, object) V8JS_BEGIN_CTX(c, object)
v8::HandleScope handle_scope(c->isolate);
/* Global PHP JS object */ /* Global PHP JS object */
v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(c->object_name)->ToObject(); v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(c->isolate, c->object_name);
v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(object_name_js)->ToObject();
/* Delete value from PHP JS object */ /* Delete value from PHP JS object */
jsobj->ForceDelete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member))); jsobj->ForceDelete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)));

View File

@ -26,11 +26,25 @@ extern "C" {
#include "php_v8js_macros.h" #include "php_v8js_macros.h"
#include <v8.h> #include <v8.h>
#include <map>
#include <stdexcept> #include <stdexcept>
typedef std::pair<v8::Isolate *, const char *> TemplateCacheKey; namespace v8 {
typedef std::map<TemplateCacheKey, v8::Persistent<v8::FunctionTemplate> > TemplateCache; template<class T>
struct CopyablePersistentTraits {
typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
static const bool kResetInDestructor = true;
template<class S, class M>
V8_INLINE(static void Copy(const Persistent<S, M>& source,
CopyablePersistent* dest)) {
// do nothing, just allow copy
}
};
}
typedef std::pair<struct php_v8js_ctx *, const char *> TemplateCacheKey;
typedef v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate> > TemplateCacheEntry;
typedef std::map<TemplateCacheKey, TemplateCacheEntry> TemplateCache;
/* Callback for PHP methods and functions */ /* Callback for PHP methods and functions */
static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info) /* {{{ */ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info) /* {{{ */
@ -373,14 +387,18 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
/* Object methods */ /* Object methods */
if (ce == php_ce_v8_function) { if (ce == php_ce_v8_function) {
php_v8js_object *c = (php_v8js_object *) zend_object_store_get_object(value TSRMLS_CC); php_v8js_object *c = (php_v8js_object *) zend_object_store_get_object(value TSRMLS_CC);
return c->v8obj; v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, c->v8obj);
return v8obj;
} else if (ce) { } else if (ce) {
v8::Handle<v8::FunctionTemplate> new_tpl; php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
v8::Local<v8::FunctionTemplate> new_tpl;
bool cached_tpl = true; bool cached_tpl = true;
static TemplateCache tpl_map; static TemplateCache tpl_map;
try { try {
new_tpl = tpl_map.at(std::make_pair(isolate, ce->name)); new_tpl = v8::Local<v8::FunctionTemplate>::New
(isolate, tpl_map.at(std::make_pair(ctx, ce->name)));
} }
catch (const std::out_of_range &) { catch (const std::out_of_range &) {
cached_tpl = false; cached_tpl = false;
@ -399,8 +417,8 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_php_callback); new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_php_callback);
} else { } else {
/* Add new v8::FunctionTemplate to tpl_map, as long as it is not a closure. */ /* Add new v8::FunctionTemplate to tpl_map, as long as it is not a closure. */
tpl_map[std::make_pair(isolate, ce->name)] = TemplateCacheEntry tce(isolate, new_tpl);
v8::Persistent<v8::FunctionTemplate>::New(isolate, new_tpl); tpl_map[std::make_pair(ctx, ce->name)] = tce;
} }
} }
@ -477,15 +495,14 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
// decides to dispose the JS object, we add a weak persistent handle and register // decides to dispose the JS object, we add a weak persistent handle and register
// a callback function that removes the reference. // a callback function that removes the reference.
v8::Handle<v8::Value> external = v8::External::New(value); v8::Handle<v8::Value> external = v8::External::New(value);
v8::Persistent<v8::Object> persist_newobj = v8::Persistent<v8::Object>::New v8::Persistent<v8::Object> persist_newobj(isolate, new_tpl->GetFunction()->NewInstance(1, &external));
(isolate, new_tpl->GetFunction()->NewInstance(1, &external));
persist_newobj.MakeWeak(value, php_v8js_weak_object_callback); persist_newobj.MakeWeak(value, php_v8js_weak_object_callback);
// Just tell v8 that we're allocating some external memory // Just tell v8 that we're allocating some external memory
// (for the moment we just always tell 1k instead of trying to find out actual values) // (for the moment we just always tell 1k instead of trying to find out actual values)
v8::V8::AdjustAmountOfExternalAllocatedMemory(1024); v8::V8::AdjustAmountOfExternalAllocatedMemory(1024);
newobj = persist_newobj; newobj = v8::Local<v8::Object>::New(isolate, persist_newobj);
if (ce != zend_ce_closure) { if (ce != zend_ce_closure) {
// These unfortunately cannot be attached to the template, hence we have to put them // These unfortunately cannot be attached to the template, hence we have to put them

View File

@ -270,7 +270,7 @@ V8JS_METHOD(require)
global->Set(v8::String::New("module"), module); global->Set(v8::String::New("module"), module);
// Each module gets its own context so different modules do not affect each other // Each module gets its own context so different modules do not affect each other
v8::Persistent<v8::Context> context = v8::Persistent<v8::Context>::New(c->isolate, v8::Context::New(c->isolate, NULL, global)); v8::Local<v8::Context> context = v8::Local<v8::Context>::New(c->isolate, v8::Context::New(c->isolate, NULL, global));
// Catch JS exceptions // Catch JS exceptions
v8::TryCatch try_catch; v8::TryCatch try_catch;