0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-09-19 21:15:19 +00:00

Merge branch 'issue-104', closes #104

This commit is contained in:
Stefan Siegl 2014-10-19 12:42:57 +00:00
commit 51930e7bca
6 changed files with 26 additions and 129 deletions

View File

@ -14,7 +14,7 @@ Minimum requirements
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 implements ECMAScript as specified in ECMA-262, 5th edition.
This extension makes use of V8 isolates to ensure separation between multiple V8Js instances and uses the new isolate-based mechanism to throw exceptions, hence the need for 3.22.3 or above.
This extension makes use of V8 isolates to ensure separation between multiple V8Js instances and uses the new isolate-based mechanism to throw exceptions, hence the need for 3.24.10 or above.
For a detailed overview of which V8 version V8Js can be successfully built against, see the [Jenkins V8Js job list](http://jenkins.brokenpipe.de/view/v8js-with-v8-versions/).

View File

@ -39,37 +39,16 @@ extern "C" {
/* V8Js Version */
#define V8JS_VERSION "0.1.5"
/* V8 from 3.23.12 has most v8::Anything::New constructors expect isolates
as their first argument. Older versions don't provide these. */
#if PHP_V8_API_VERSION < 3023012
#define V8JS_NEW(t, i, v...) t::New(v)
#else
#define V8JS_NEW(t, i, v...) t::New(i, v)
#endif
/* Helper macros */
#define V8JS_SYM(v) v8::String::NewFromUtf8(isolate, v, v8::String::kInternalizedString, sizeof(v) - 1)
#define V8JS_SYML(v, l) v8::String::NewFromUtf8(isolate, v, v8::String::kInternalizedString, l)
#define V8JS_STR(v) v8::String::NewFromUtf8(isolate, v)
#define V8JS_STRL(v, l) v8::String::NewFromUtf8(isolate, v, v8::String::kNormalString, l)
#if PHP_V8_API_VERSION < 3024010
#define V8JS_INT(v) v8::Integer::New(v, isolate)
#define V8JS_UINT(v) v8::Integer::NewFromUnsigned(v, isolate)
#else
#define V8JS_INT(v) v8::Integer::New(isolate, v)
#define V8JS_UINT(v) v8::Integer::NewFromUnsigned(isolate, v)
#endif
#define V8JS_FLOAT(v) v8::Number::New(isolate, v)
#define V8JS_BOOL(v) ((v)?v8::True(isolate):v8::False(isolate))
#if PHP_V8_API_VERSION <= 3023012
#define V8JS_DATE(v) v8::Date::New(v)
#else
#define V8JS_DATE(v) v8::Date::New(isolate, v)
#endif
#define V8JS_NULL v8::Null(isolate)
#define V8JS_UNDEFINED v8::Undefined(isolate)
#define V8JS_MN(name) v8js_method_##name
@ -77,29 +56,6 @@ extern "C" {
#define V8JS_THROW(isolate, type, message, message_len) (isolate)->ThrowException(v8::Exception::type(V8JS_STRL(message, message_len)))
#define V8JS_GLOBAL(isolate) ((isolate)->GetCurrentContext()->Global())
#if PHP_V8_API_VERSION < 3022000
/* CopyablePersistentTraits is only part of V8 from 3.22.0 on,
to be compatible with lower versions add our own (compatible) version. */
namespace v8 {
template<class T>
struct CopyablePersistentTraits {
typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
static const bool kResetInDestructor = true;
template<class S, class M>
#if PHP_V8_API_VERSION >= 3021015
static V8_INLINE void Copy(const Persistent<S, M>& source,
CopyablePersistent* dest)
#else
V8_INLINE(static void Copy(const Persistent<S, M>& source,
CopyablePersistent* dest))
#endif
{
// do nothing, just allow copy
}
};
}
#endif
/* Abbreviate long type names */
typedef v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate> > v8js_tmpl_t;
typedef v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > v8js_persistent_obj_t;
@ -108,15 +64,8 @@ typedef v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > v8
#define PHPJS_OBJECT_KEY "phpjs::object"
/* Helper macros */
#if PHP_V8_API_VERSION < 2005009
# define V8JS_GET_CLASS_NAME(var, obj) \
/* Hack to prevent calling possibly set user-defined __toString() messing class name */ \
v8::Local<v8::Function> constructor = v8::Local<v8::Function>::Cast(obj->Get(V8JS_SYM("constructor"))); \
v8::String::Utf8Value var(constructor->GetName());
#else
# define V8JS_GET_CLASS_NAME(var, obj) \
#define V8JS_GET_CLASS_NAME(var, obj) \
v8::String::Utf8Value var(obj->GetConstructorName());
#endif
#if ZEND_MODULE_API_NO >= 20100409
# define ZEND_HASH_KEY_DC , const zend_literal *key
@ -217,12 +166,7 @@ struct php_v8js_ctx {
/* }}} */
#ifdef ZTS
# if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
# define V8JS_TSRMLS_FETCH() TSRMLS_FETCH_FROM_CTX(((php_v8js_ctx *) isolate->GetData())->zts_ctx);
# else
# define V8JS_TSRMLS_FETCH() TSRMLS_FETCH_FROM_CTX(((php_v8js_ctx *) isolate->GetData(0))->zts_ctx);
# endif
# define V8JS_TSRMLS_FETCH() TSRMLS_FETCH_FROM_CTX(((php_v8js_ctx *) isolate->GetData(0))->zts_ctx);
#else
# define V8JS_TSRMLS_FETCH()
#endif

19
v8js.cc
View File

@ -606,13 +606,7 @@ PHP_METHOD(V8Function,__construct)
void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
php_v8js_object *c;
object_init_ex(res, value->IsFunction() ? php_ce_v8_function : php_ce_v8_object);
@ -924,12 +918,7 @@ static PHP_METHOD(V8Js, __construct)
c->pending_exception = NULL;
c->in_execution = 0;
c->isolate = v8::Isolate::New();
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
c->isolate->SetData(c);
#else
c->isolate->SetData(0, c);
#endif
c->time_limit_hit = false;
c->memory_limit_hit = false;
c->module_loader = NULL;
@ -963,7 +952,7 @@ static PHP_METHOD(V8Js, __construct)
/* Create global template for global object */
// Now we are using multiple isolates this needs to be created for every context
v8::Local<v8::FunctionTemplate> tpl = V8JS_NEW(v8::FunctionTemplate, c->isolate, 0);
v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(c->isolate, 0);
tpl->SetClassName(V8JS_SYM("V8Js"));
c->global_template.Reset(isolate, tpl);
@ -991,7 +980,7 @@ static PHP_METHOD(V8Js, __construct)
v8::Context::Scope context_scope(context);
/* Create the PHP container object's function template */
v8::Local<v8::FunctionTemplate> php_obj_t = V8JS_NEW(v8::FunctionTemplate, isolate, 0);
v8::Local<v8::FunctionTemplate> php_obj_t = v8::FunctionTemplate::New(isolate, 0);
/* Set class name for PHP object */
#if PHP_VERSION_ID >= 50400
@ -1212,11 +1201,7 @@ static void php_v8js_execute_script(zval *this_ptr, php_v8js_script *res, long f
c->tz = strdup(tz);
}
else if (strcmp(c->tz, tz) != 0) {
#if PHP_V8_API_VERSION <= 3023012
v8::Date::DateTimeConfigurationChangeNotification();
#else
v8::Date::DateTimeConfigurationChangeNotification(c->isolate);
#endif
free(c->tz);
c->tz = strdup(tz);

View File

@ -78,12 +78,7 @@ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_funct
char *error;
int error_len, i, flags = V8JS_FLAG_NONE;
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
/* Set parameter limits */
min_num_args = method_ptr->common.required_num_args;
@ -278,12 +273,7 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
v8::Local<v8::External> ext_tmpl = v8::Local<v8::External>::Cast(cons_data->Get(0));
v8::Local<v8::External> ext_ce = v8::Local<v8::External>::Cast(cons_data->Get(1));
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
if (info[0]->IsExternal()) {
// Object created by v8js in php_v8js_hash_to_jsobj, PHP object passed as v8::External.
@ -318,7 +308,7 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
if (ctor_ptr != NULL) {
php_v8js_call_php_func(value, ce, ctor_ptr, isolate, info TSRMLS_CC);
}
php_object = V8JS_NEW(v8::External, isolate, value);
php_object = v8::External::New(isolate, value);
}
newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value());
@ -364,12 +354,7 @@ static void php_v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object,
zval *value = data.GetParameter();
zval_ptr_dtor(&value);
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
ctx->weak_objects.at(value).Reset();
ctx->weak_objects.erase(value);
@ -384,12 +369,7 @@ static void php_v8js_weak_closure_callback(const v8::WeakCallbackData<v8::Object
persist_tpl_->Reset();
delete persist_tpl_;
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
ctx->weak_closures.at(persist_tpl_).Reset();
ctx->weak_closures.erase(persist_tpl_);
@ -405,7 +385,7 @@ static void php_v8js_weak_closure_callback(const v8::WeakCallbackData<v8::Object
!strncasecmp(key, mname, key_len - 1))
#define PHP_V8JS_CALLBACK(isolate, mptr, tmpl) \
V8JS_NEW(v8::FunctionTemplate, (isolate), php_v8js_php_callback, V8JS_NEW(v8::External, (isolate), mptr), V8JS_NEW(v8::Signature, (isolate), tmpl))->GetFunction()
v8::FunctionTemplate::New((isolate), php_v8js_php_callback, v8::External::New((isolate), mptr), v8::Signature::New((isolate), tmpl))->GetFunction()
static void php_v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Array> &info) /* {{{ */
@ -413,7 +393,7 @@ static void php_v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8
// note: 'special' properties like 'constructor' are not enumerated.
v8::Isolate *isolate = info.GetIsolate();
v8::Local<v8::Object> self = info.Holder();
v8::Local<v8::Array> result = V8JS_NEW(v8::Array, isolate, 0);
v8::Local<v8::Array> result = v8::Array::New(isolate, 0);
uint32_t result_len = 0;
V8JS_TSRMLS_FETCH();
@ -520,12 +500,7 @@ static void php_v8js_invoke_callback(const v8::FunctionCallbackInfo<v8::Value>&
}
if (info.IsConstructCall()) {
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
v8::String::Utf8Value str(self->GetConstructorName()->ToString());
const char *constructor_name = ToCString(str);
@ -690,9 +665,9 @@ static inline v8::Local<v8::Value> php_v8js_named_property_callback(v8::Local<v8
// (only use this if method_ptr==NULL, which means
// there is no actual PHP __call() implementation)
v8::Local<v8::Function> cb =
V8JS_NEW(v8::FunctionTemplate, isolate,
v8::FunctionTemplate::New(isolate,
php_v8js_fake_call_impl, V8JS_NULL,
V8JS_NEW(v8::Signature, isolate, tmpl))->GetFunction();
v8::Signature::New(isolate, tmpl))->GetFunction();
cb->SetName(property);
ret_value = cb;
} else {
@ -916,12 +891,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
return v8obj;
} else if (ce) {
#if PHP_V8_API_VERSION <= 3023008
/* Until V8 3.23.8 Isolate could only take one external pointer. */
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData();
#else
php_v8js_ctx *ctx = (php_v8js_ctx *) isolate->GetData(0);
#endif
v8::Local<v8::FunctionTemplate> new_tpl;
v8js_tmpl_t *persist_tpl_;
@ -931,7 +901,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
}
catch (const std::out_of_range &) {
/* No cached v8::FunctionTemplate available as of yet, create one. */
new_tpl = V8JS_NEW(v8::FunctionTemplate, isolate, 0);
new_tpl = v8::FunctionTemplate::New(isolate, 0);
new_tpl->SetClassName(V8JS_STRL(ce->name, ce->name_length));
new_tpl->InstanceTemplate()->SetInternalFieldCount(1);
@ -964,14 +934,14 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_invoke_callback, PHP_V8JS_CALLBACK(isolate, invoke_method_ptr, new_tpl));
}
}
v8::Local<v8::Array> call_handler_data = V8JS_NEW(v8::Array, isolate, 2);
call_handler_data->Set(0, V8JS_NEW(v8::External, isolate, persist_tpl_));
call_handler_data->Set(1, V8JS_NEW(v8::External, isolate, ce));
v8::Local<v8::Array> call_handler_data = v8::Array::New(isolate, 2);
call_handler_data->Set(0, v8::External::New(isolate, persist_tpl_));
call_handler_data->Set(1, v8::External::New(isolate, ce));
new_tpl->SetCallHandler(php_v8js_construct_callback, call_handler_data);
}
// Create v8 wrapper object
v8::Handle<v8::Value> external = V8JS_NEW(v8::External, isolate, value);
v8::Handle<v8::Value> external = v8::External::New(isolate, value);
newobj = new_tpl->GetFunction()->NewInstance(1, &external);
if (ce == zend_ce_closure) {
@ -981,7 +951,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
}
} else {
// @todo re-use template likewise
v8::Local<v8::FunctionTemplate> new_tpl = V8JS_NEW(v8::FunctionTemplate, isolate, 0);
v8::Local<v8::FunctionTemplate> new_tpl = v8::FunctionTemplate::New(isolate, 0);
new_tpl->SetClassName(V8JS_SYM("Array"));
newobj = new_tpl->InstanceTemplate()->NewInstance();
@ -1050,7 +1020,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value, v8::Isolate *is
return V8JS_NULL;
}
newarr = V8JS_NEW(v8::Array, isolate, i);
newarr = v8::Array::New(isolate, i);
if (i > 0)
{

View File

@ -113,12 +113,10 @@ static void _php_v8js_dumper(v8::Isolate *isolate, v8::Local<v8::Value> var, int
// fake the fields of a PHP DateTime
php_printf("Date(%s)\n", valstr);
}
#if PHP_V8_API_VERSION >= 2003007
else if (var->IsRegExp())
{
php_printf("regexp(%s)\n", valstr);
}
#endif
else if (var->IsArray())
{
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(var);
@ -302,9 +300,9 @@ V8JS_METHOD(require)
// Create a template for the global object and set the built-in global functions
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
global->Set(V8JS_SYM("print"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(print)), v8::ReadOnly);
global->Set(V8JS_SYM("sleep"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(sleep)), v8::ReadOnly);
global->Set(V8JS_SYM("require"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(require), V8JS_NEW(v8::External, isolate, c)), v8::ReadOnly);
global->Set(V8JS_SYM("print"), v8::FunctionTemplate::New(isolate, V8JS_MN(print)), v8::ReadOnly);
global->Set(V8JS_SYM("sleep"), v8::FunctionTemplate::New(isolate, V8JS_MN(sleep)), v8::ReadOnly);
global->Set(V8JS_SYM("require"), v8::FunctionTemplate::New(isolate, V8JS_MN(require), v8::External::New(isolate, c)), v8::ReadOnly);
// Add the exports object in which the module can return its API
v8::Local<v8::ObjectTemplate> exports_template = v8::ObjectTemplate::New();
@ -396,13 +394,13 @@ V8JS_METHOD(require)
void php_v8js_register_methods(v8::Handle<v8::ObjectTemplate> global, php_v8js_ctx *c) /* {{{ */
{
v8::Isolate *isolate = c->isolate;
global->Set(V8JS_SYM("exit"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(exit)), v8::ReadOnly);
global->Set(V8JS_SYM("sleep"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(sleep)), v8::ReadOnly);
global->Set(V8JS_SYM("print"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(print)), v8::ReadOnly);
global->Set(V8JS_SYM("var_dump"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(var_dump)), v8::ReadOnly);
global->Set(V8JS_SYM("exit"), v8::FunctionTemplate::New(isolate, V8JS_MN(exit)), v8::ReadOnly);
global->Set(V8JS_SYM("sleep"), v8::FunctionTemplate::New(isolate, V8JS_MN(sleep)), v8::ReadOnly);
global->Set(V8JS_SYM("print"), v8::FunctionTemplate::New(isolate, V8JS_MN(print)), v8::ReadOnly);
global->Set(V8JS_SYM("var_dump"), v8::FunctionTemplate::New(isolate, V8JS_MN(var_dump)), v8::ReadOnly);
c->modules_base.push_back("");
global->Set(V8JS_SYM("require"), V8JS_NEW(v8::FunctionTemplate, isolate, V8JS_MN(require), V8JS_NEW(v8::External, isolate, c)), v8::ReadOnly);
global->Set(V8JS_SYM("require"), v8::FunctionTemplate::New(isolate, V8JS_MN(require), v8::External::New(isolate, c)), v8::ReadOnly);
}
/* }}} */

View File

@ -86,7 +86,7 @@ void php_v8js_register_accessors(std::vector<php_v8js_accessor_ctx*> *accessor_l
ctx->isolate = isolate;
/* Set the variable fetch callback for given symbol on named property */
php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, V8JS_NEW(v8::External, isolate, ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly, V8JS_NEW(v8::AccessorSignature, isolate, php_obj_t));
php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, v8::External::New(isolate, ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly, v8::AccessorSignature::New(isolate, php_obj_t));
/* record the context so we can free it later */
accessor_list->push_back(ctx);