0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-11-14 03:48:41 +00:00

Use prologues for V8Function calls, closes #129

This commit is contained in:
Stefan Siegl 2014-12-07 15:19:47 +01:00
parent acd00af78a
commit 2a1ae43496
3 changed files with 95 additions and 19 deletions

View File

@ -0,0 +1,41 @@
--TEST--
Test V8::setMemoryLimit() : Memory limit applied to V8Function calls
--SKIPIF--
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--FILE--
<?php
$JS = <<< EOT
var jsfunc = function() {
var text = "abcdefghijklmnopqrstuvwyxz0123456789";
var memory = "";
for (var i = 0; i < 100; ++i) {
for (var j = 0; j < 10000; ++j) {
memory += text;
}
sleep(0);
}
};
jsfunc;
EOT;
$v8 = new V8Js();
$v8->setMemoryLimit(10000000);
$func = $v8->executeString($JS);
var_dump($func);
try {
$func();
} catch (V8JsMemoryLimitException $e) {
print get_class($e); print PHP_EOL;
print $e->getMessage(); print PHP_EOL;
}
?>
===EOF===
--EXPECTF--
object(V8Function)#%d (0) {
}
V8JsMemoryLimitException
Script memory limit of 10000000 bytes exceeded
===EOF===

View File

@ -0,0 +1,37 @@
--TEST--
Test V8::setTimeLimit() : Time limit applied to V8Function calls
--SKIPIF--
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--FILE--
<?php
$JS = <<< EOT
var jsfunc = function() {
var text = "abcdefghijklmnopqrstuvwyxz0123456789";
for (var i = 0; i < 10000000; ++i) {
var encoded = encodeURI(text);
}
};
jsfunc;
EOT;
$v8 = new V8Js();
$v8->setTimeLimit(100);
$func = $v8->executeString($JS);
var_dump($func);
try {
$func();
} catch (V8JsTimeLimitException $e) {
print get_class($e); print PHP_EOL;
print $e->getMessage(); print PHP_EOL;
}
?>
===EOF===
--EXPECTF--
object(V8Function)#%d (0) {
}
V8JsTimeLimitException
Script time limit of 100 milliseconds exceeded
===EOF===

36
v8js.cc
View File

@ -40,6 +40,10 @@ extern "C" {
/* Forward declarations */ /* Forward declarations */
static void php_v8js_throw_script_exception(v8::TryCatch * TSRMLS_DC); static void php_v8js_throw_script_exception(v8::TryCatch * TSRMLS_DC);
static void php_v8js_create_script_exception(zval *, v8::TryCatch * TSRMLS_DC); static void php_v8js_create_script_exception(zval *, v8::TryCatch * TSRMLS_DC);
static void php_v8js_call_v8(php_v8js_ctx *ctx, zval **return_value,
long flags, long time_limit, long memory_limit,
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call TSRMLS_DC);
ZEND_DECLARE_MODULE_GLOBALS(v8js) ZEND_DECLARE_MODULE_GLOBALS(v8js)
@ -488,26 +492,18 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(*argv[i], isolate TSRMLS_CC)); jsArgv[i] = v8::Local<v8::Value>::New(isolate, zval_to_v8js(*argv[i], isolate TSRMLS_CC));
} }
/* Catch JS exceptions */
v8::TryCatch try_catch;
js_retval = cb->Call(V8JS_GLOBAL(isolate), argc, jsArgv); std::function< v8::Local<v8::Value>(v8::Isolate *) > v8_call = [cb, argc, jsArgv](v8::Isolate *isolate) {
return cb->Call(V8JS_GLOBAL(isolate), argc, jsArgv);
};
php_v8js_call_v8(obj->ctx, &return_value, obj->flags, obj->ctx->time_limit, obj->ctx->memory_limit, v8_call TSRMLS_CC);
zval_ptr_dtor(&object); zval_ptr_dtor(&object);
if (argc > 0) { if (argc > 0) {
efree(argv); efree(argv);
} }
if (try_catch.HasCaught()) {
php_v8js_throw_script_exception(&try_catch TSRMLS_CC);
return FAILURE;
}
if (return_value_used) {
return v8js_to_zval(js_retval, return_value, obj->flags, isolate TSRMLS_CC);
}
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -1038,15 +1034,12 @@ static PHP_METHOD(V8Js, __construct)
} }
/* }}} */ /* }}} */
#define V8JS_BEGIN_CTX(ctx, object) \ #define V8JS_CTX_PROLOGUE(ctx) \
php_v8js_ctx *(ctx); \
\
if (!V8JSG(v8_initialized)) { \ if (!V8JSG(v8_initialized)) { \
zend_error(E_ERROR, "V8 not initialized"); \ zend_error(E_ERROR, "V8 not initialized"); \
return; \ return; \
} \ } \
\ \
(ctx) = (php_v8js_ctx *) zend_object_store_get_object(object TSRMLS_CC); \
v8::Isolate *isolate = (ctx)->isolate; \ v8::Isolate *isolate = (ctx)->isolate; \
v8::Locker locker(isolate); \ v8::Locker locker(isolate); \
v8::Isolate::Scope isolate_scope(isolate); \ v8::Isolate::Scope isolate_scope(isolate); \
@ -1054,6 +1047,11 @@ static PHP_METHOD(V8Js, __construct)
v8::Local<v8::Context> v8_context = v8::Local<v8::Context>::New(isolate, (ctx)->context); \ v8::Local<v8::Context> v8_context = v8::Local<v8::Context>::New(isolate, (ctx)->context); \
v8::Context::Scope context_scope(v8_context); v8::Context::Scope context_scope(v8_context);
#define V8JS_BEGIN_CTX(ctx, object) \
php_v8js_ctx *(ctx); \
(ctx) = (php_v8js_ctx *) zend_object_store_get_object(object TSRMLS_CC); \
V8JS_CTX_PROLOGUE(ctx);
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)
{ {
V8JSG(timer_mutex).lock(); V8JSG(timer_mutex).lock();
@ -1175,13 +1173,13 @@ static void php_v8js_compile_script(zval *this_ptr, const char *str, int str_len
} }
static void php_v8js_call_v8(zval *this_ptr, zval **return_value, static void php_v8js_call_v8(php_v8js_ctx *c, zval **return_value,
long flags, long time_limit, long memory_limit, long flags, long time_limit, long memory_limit,
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call TSRMLS_DC) /* {{{ */ std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call TSRMLS_DC) /* {{{ */
{ {
char *tz = NULL; char *tz = NULL;
V8JS_BEGIN_CTX(c, this_ptr) V8JS_CTX_PROLOGUE(c);
V8JSG(timer_mutex).lock(); V8JSG(timer_mutex).lock();
c->time_limit_hit = false; c->time_limit_hit = false;
@ -1330,7 +1328,7 @@ static void php_v8js_execute_script(zval *this_ptr, php_v8js_script *res, long f
return script->Run(); return script->Run();
}; };
php_v8js_call_v8(this_ptr, return_value, flags, time_limit, memory_limit, v8_call TSRMLS_CC); php_v8js_call_v8(c, return_value, flags, time_limit, memory_limit, v8_call TSRMLS_CC);
} }
/* {{{ proto mixed V8Js::executeString(string script [, string identifier [, int flags]]) /* {{{ proto mixed V8Js::executeString(string script [, string identifier [, int flags]])