Skip to content

Commit

Permalink
export public methods of classes derived from \V8Js, closes phpv8#183
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Siegl committed Jan 8, 2016
1 parent 0945749 commit 3508f0c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
7 changes: 7 additions & 0 deletions php_v8js_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ extern "C" {
#define V8JS_FLAG_FORCE_ARRAY (1<<1)
#define V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS (1<<2)


/* These are not defined by Zend */
#define ZEND_WAKEUP_FUNC_NAME "__wakeup"
#define ZEND_SLEEP_FUNC_NAME "__sleep"
#define ZEND_SET_STATE_FUNC_NAME "__set_state"


/* Convert zval into V8 value */
v8::Handle<v8::Value> zval_to_v8js(zval *, v8::Isolate * TSRMLS_DC);

Expand Down
63 changes: 63 additions & 0 deletions v8js_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern "C" {
#include "v8js_v8.h"
#include "v8js_exceptions.h"
#include "v8js_v8object_class.h"
#include "v8js_object_export.h"
#include "v8js_timer.h"

#include <functional>
Expand Down Expand Up @@ -319,6 +320,10 @@ static void v8js_fatal_error_handler(const char *location, const char *message)
}
/* }}} */

#define IS_MAGIC_FUNC(mname) \
((key_len == sizeof(mname)) && \
!strncasecmp(key, mname, key_len - 1))

/* {{{ proto void V8Js::__construct([string object_name [, array variables [, array extensions [, bool report_uncaught_exceptions]]])
__construct for V8Js */
static PHP_METHOD(V8Js, __construct)
Expand Down Expand Up @@ -480,7 +485,65 @@ static PHP_METHOD(V8Js, __construct)
}
}

/* Add pointer to zend object */
php_obj->SetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY), v8::External::New(isolate, getThis()));

/* Export public methods */
zend_function *method_ptr;
char *key = NULL;
uint key_len;

zend_hash_internal_pointer_reset_ex(&c->std.ce->function_table, &pos);
for (;; zend_hash_move_forward_ex(&c->std.ce->function_table, &pos)) {
if (zend_hash_get_current_key_ex(&c->std.ce->function_table, &key, &key_len, &index, 0, &pos) != HASH_KEY_IS_STRING ||
zend_hash_get_current_data_ex(&c->std.ce->function_table, (void **) &method_ptr, &pos) == FAILURE
) {
break;
}

if ((method_ptr->common.fn_flags & ZEND_ACC_PUBLIC) == 0) {
/* Allow only public methods */
continue;
}

if ((method_ptr->common.fn_flags & (ZEND_ACC_CTOR|ZEND_ACC_DTOR|ZEND_ACC_CLONE)) != 0) {
/* no __construct, __destruct(), or __clone() functions */
continue;
}

/* hide (do not export) other PHP magic functions */
if (IS_MAGIC_FUNC(ZEND_CALLSTATIC_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_SLEEP_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_WAKEUP_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_SET_STATE_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_GET_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_SET_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_UNSET_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_CALL_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_INVOKE_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME) ||
IS_MAGIC_FUNC(ZEND_ISSET_FUNC_NAME)) {
continue;
}

v8::Local<v8::String> method_name = V8JS_STR(method_ptr->common.function_name);
v8::Local<v8::FunctionTemplate> ft;

try {
ft = v8::Local<v8::FunctionTemplate>::New
(isolate, c->method_tmpls.at(method_ptr));
}
catch (const std::out_of_range &) {
ft = v8::FunctionTemplate::New(isolate, v8js_php_callback,
v8::External::New((isolate), method_ptr));
// @fixme add/check Signature v8::Signature::New((isolate), tmpl));
v8js_tmpl_t *persistent_ft = &c->method_tmpls[method_ptr];
persistent_ft->Reset(isolate, ft);
}


php_obj->ForceSet(method_name, ft->GetFunction());
}
}
/* }}} */

Expand Down
7 changes: 1 addition & 6 deletions v8js_object_export.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function
/* }}} */

/* Callback for PHP methods and functions */
static void v8js_php_callback(const v8::FunctionCallbackInfo<v8::Value>& info) /* {{{ */
void v8js_php_callback(const v8::FunctionCallbackInfo<v8::Value>& info) /* {{{ */
{
v8::Isolate *isolate = info.GetIsolate();
v8::Local<v8::Object> self = info.Holder();
Expand Down Expand Up @@ -291,11 +291,6 @@ static void v8js_weak_closure_callback(const v8::WeakCallbackData<v8::Object, v8
ctx->weak_closures.erase(persist_tpl_);
};

/* These are not defined by Zend */
#define ZEND_WAKEUP_FUNC_NAME "__wakeup"
#define ZEND_SLEEP_FUNC_NAME "__sleep"
#define ZEND_SET_STATE_FUNC_NAME "__set_state"

#define IS_MAGIC_FUNC(mname) \
((key_len == sizeof(mname)) && \
!strncasecmp(key, mname, key_len - 1))
Expand Down
2 changes: 2 additions & 0 deletions v8js_object_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property
property_op_t callback_type,
v8::Local<v8::Value> set_value = v8::Local<v8::Value>());

void v8js_php_callback(const v8::FunctionCallbackInfo<v8::Value>& info);

#endif /* V8JS_OBJECT_EXPORT_H */

0 comments on commit 3508f0c

Please sign in to comment.