php_vm 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/php_vm/php_vm.c +110 -24
- data/ext/php_vm/php_vm.h +2 -0
- metadata +2 -2
data/ext/php_vm/php_vm.c
CHANGED
@@ -48,7 +48,7 @@ static void php_embed_error_handler(char *message)
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
|
51
|
-
static void
|
51
|
+
static void php_vm_exception_hook(zval *ex TSRMLS_DC)
|
52
52
|
{
|
53
53
|
VALUE exception = zval_to_value(ex);
|
54
54
|
rb_exc_raise(exception);
|
@@ -154,6 +154,13 @@ void find_zend_function(zend_class_entry *ce, char *name, int name_len, zend_fun
|
|
154
154
|
free(lcname);
|
155
155
|
}
|
156
156
|
|
157
|
+
int has_zend_function(zend_class_entry *ce, VALUE method_name)
|
158
|
+
{
|
159
|
+
zend_function *mptr;
|
160
|
+
find_zend_function(ce, RSTRING_PTR(method_name), RSTRING_LEN(method_name), &mptr);
|
161
|
+
return mptr!=NULL;
|
162
|
+
}
|
163
|
+
|
157
164
|
int new_php_object(zend_class_entry *ce, VALUE v_args, zval *retval)
|
158
165
|
{
|
159
166
|
int result = FAILURE;
|
@@ -240,10 +247,6 @@ void define_php_methods(VALUE v_obj, zend_class_entry *ce, int is_static)
|
|
240
247
|
// TODO: access scope
|
241
248
|
// TODO: __toString
|
242
249
|
// TODO: __clone
|
243
|
-
// TODO: __call
|
244
|
-
// TODO: __callStatic
|
245
|
-
// TODO: __get
|
246
|
-
// TODO: __set
|
247
250
|
// TODO: __isset
|
248
251
|
|
249
252
|
HashPosition pos;
|
@@ -254,24 +257,49 @@ void define_php_methods(VALUE v_obj, zend_class_entry *ce, int is_static)
|
|
254
257
|
while (zend_hash_get_current_data_ex(&ce->function_table, (void **)&mptr, &pos) == SUCCESS) {
|
255
258
|
int flag = mptr->common.fn_flags;
|
256
259
|
const char *fname = mptr->common.function_name;
|
260
|
+
int is_pass_define = 0;
|
257
261
|
|
258
262
|
if (is_static) {
|
259
263
|
// class method
|
260
|
-
if (
|
261
|
-
|
264
|
+
if (0<(flag & ZEND_ACC_STATIC)) {
|
265
|
+
if (strcmp("new", fname)==0) {
|
266
|
+
// new => no define
|
267
|
+
is_pass_define = 1;
|
262
268
|
|
263
|
-
|
264
|
-
|
265
|
-
|
269
|
+
} else if (strcmp("__callStatic", fname)==0) {
|
270
|
+
// __callStatic => method_missing
|
271
|
+
rb_define_singleton_method(v_obj, "method_missing", rb_php_class_call_method_missing, -1);
|
272
|
+
}
|
273
|
+
|
274
|
+
// define
|
275
|
+
if (!is_pass_define) {
|
276
|
+
rb_define_singleton_method(v_obj, fname, rb_php_class_call, -1);
|
277
|
+
}
|
266
278
|
}
|
267
279
|
} else {
|
268
280
|
// instance method
|
269
|
-
if (
|
270
|
-
|
281
|
+
if (0==(flag & ZEND_ACC_STATIC)) {
|
282
|
+
if (strcmp("__construct", fname)==0 || strcmp(ce->name, fname)==0) {
|
283
|
+
// __construct => no define
|
284
|
+
is_pass_define = 1;
|
285
|
+
|
286
|
+
} else if (strcmp("__call", fname)==0) {
|
287
|
+
// __call => method_missing
|
288
|
+
rb_define_singleton_method(v_obj, "method_missing", rb_php_object_call_method_missing, -1);
|
289
|
+
|
290
|
+
} else if (strcmp("__get", fname)==0) {
|
291
|
+
// __get => method_missing
|
292
|
+
rb_define_singleton_method(v_obj, "method_missing", rb_php_object_call_method_missing, -1);
|
293
|
+
|
294
|
+
} else if (strcmp("__set", fname)==0) {
|
295
|
+
// __set => method_missing
|
296
|
+
rb_define_singleton_method(v_obj, "method_missing", rb_php_object_call_method_missing, -1);
|
297
|
+
}
|
271
298
|
|
272
|
-
} else if (0==(flag & ZEND_ACC_STATIC)) {
|
273
299
|
// other method
|
274
|
-
|
300
|
+
if (!is_pass_define) {
|
301
|
+
rb_define_singleton_method(v_obj, fname, rb_php_object_call, -1);
|
302
|
+
}
|
275
303
|
}
|
276
304
|
}
|
277
305
|
|
@@ -619,7 +647,8 @@ VALUE define_global_constants()
|
|
619
647
|
case HASH_KEY_IS_STRING:{
|
620
648
|
if (0x61<=string_key[0] && string_key[0]<=0x7a) {
|
621
649
|
// lower case
|
622
|
-
char *string_key2 = malloc(strlen(string_key));
|
650
|
+
char *string_key2 = malloc(strlen(string_key)+1);
|
651
|
+
memcpy(string_key2, string_key, strlen(string_key));
|
623
652
|
string_key2[0] = string_key2[0]-32;
|
624
653
|
if (!rb_const_defined(rb_mPHPGlobal, rb_intern(string_key2))) {
|
625
654
|
rb_define_const(rb_mPHPGlobal, string_key2, zval_to_value(*data));
|
@@ -699,11 +728,22 @@ VALUE define_global_classes()
|
|
699
728
|
|
700
729
|
HashTable* ht = Z_ARRVAL_P(z_val);
|
701
730
|
HashPosition pos;
|
702
|
-
zval**
|
731
|
+
zval** z_classname;
|
703
732
|
|
704
733
|
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
705
|
-
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&
|
706
|
-
|
734
|
+
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&z_classname, &pos)) {
|
735
|
+
char *classname = Z_STRVAL_P(*z_classname);
|
736
|
+
int classname_len = Z_STRLEN_P(*z_classname);
|
737
|
+
if (0x41<=classname[0] && classname[0]<=0x5a) {
|
738
|
+
// define class as const if class name is uppercase
|
739
|
+
if (!rb_const_defined(rb_mPHPGlobal, rb_intern(classname))) {
|
740
|
+
VALUE class = rb_php_class_get(rb_cPHPClass, rb_str_new(classname, classname_len));
|
741
|
+
rb_define_const(rb_mPHPGlobal, classname, class);
|
742
|
+
}
|
743
|
+
} else {
|
744
|
+
// define class as module function if class name is lowercase
|
745
|
+
rb_define_module_function(rb_mPHPGlobal, classname, rb_php_global_class_call, 0);
|
746
|
+
}
|
707
747
|
zend_hash_move_forward_ex(ht, &pos);
|
708
748
|
}
|
709
749
|
return Qtrue;
|
@@ -914,6 +954,17 @@ VALUE rb_php_class_call(int argc, VALUE *argv, VALUE self)
|
|
914
954
|
return call_php_method_bridge(ce, NULL, callee, argc, argv);
|
915
955
|
}
|
916
956
|
|
957
|
+
VALUE rb_php_class_call_method_missing(int argc, VALUE *argv, VALUE self)
|
958
|
+
{
|
959
|
+
zend_class_entry *ce = get_zend_class_entry(self);
|
960
|
+
|
961
|
+
VALUE name, args;
|
962
|
+
rb_scan_args(argc, argv, "1*", &name, &args);
|
963
|
+
VALUE argv2[2] = {name, args};
|
964
|
+
|
965
|
+
return call_php_method_bridge(ce, NULL, rb_str_new2("__callStatic"), 2, argv2);
|
966
|
+
}
|
967
|
+
|
917
968
|
|
918
969
|
// class PHPVM::PHPObject
|
919
970
|
|
@@ -967,6 +1018,40 @@ VALUE rb_php_object_call(int argc, VALUE *argv, VALUE self)
|
|
967
1018
|
return call_php_method_bridge(ce, zobj, callee, argc, argv);
|
968
1019
|
}
|
969
1020
|
|
1021
|
+
VALUE rb_php_object_call_method_missing(int argc, VALUE *argv, VALUE self)
|
1022
|
+
{
|
1023
|
+
zend_class_entry *ce = get_zend_class_entry(self);
|
1024
|
+
zval *zobj = get_zval(self);
|
1025
|
+
|
1026
|
+
VALUE call_method = rb_str_new2("__call");
|
1027
|
+
if (has_zend_function(ce, call_method)) {
|
1028
|
+
// __call
|
1029
|
+
VALUE name, args;
|
1030
|
+
rb_scan_args(argc, argv, "1*", &name, &args);
|
1031
|
+
name = rb_str_new2(rb_id2name(SYM2ID(name)));
|
1032
|
+
VALUE argv2[2] = {name, args};
|
1033
|
+
|
1034
|
+
return call_php_method_bridge(ce, zobj, call_method, 2, argv2);
|
1035
|
+
} else {
|
1036
|
+
// accessor
|
1037
|
+
VALUE name, val;
|
1038
|
+
rb_scan_args(argc, argv, "11", &name, &val);
|
1039
|
+
name = rb_str_new2(rb_id2name(SYM2ID(name)));
|
1040
|
+
VALUE argv2[2] = {name, val};
|
1041
|
+
|
1042
|
+
VALUE is_setter = rb_funcall(name, rb_intern("end_with?"), 1, rb_str_new2("="));
|
1043
|
+
if (is_setter) {
|
1044
|
+
// __set
|
1045
|
+
rb_funcall(name, rb_intern("gsub!"), 2, rb_str_new2("="), rb_str_new2(""));
|
1046
|
+
return call_php_method_bridge(ce, zobj, rb_str_new2("__set"), 2, argv2);
|
1047
|
+
} else {
|
1048
|
+
// __get
|
1049
|
+
return call_php_method_bridge(ce, zobj, rb_str_new2("__get"), 1, argv2);
|
1050
|
+
}
|
1051
|
+
}
|
1052
|
+
return Qnil;
|
1053
|
+
}
|
1054
|
+
|
970
1055
|
|
971
1056
|
// class PHPVM::PHPExceptionObject
|
972
1057
|
|
@@ -976,6 +1061,7 @@ VALUE rb_php_exception_object_initialize(int argc, VALUE *argv, VALUE self)
|
|
976
1061
|
return self;
|
977
1062
|
}
|
978
1063
|
|
1064
|
+
|
979
1065
|
// class PHPVM::PHPErrorReporting
|
980
1066
|
|
981
1067
|
VALUE rb_php_error_reporting_initialize(int argc, VALUE *argv, VALUE self)
|
@@ -988,7 +1074,7 @@ VALUE rb_php_error_reporting_initialize(int argc, VALUE *argv, VALUE self)
|
|
988
1074
|
|
989
1075
|
if (argc==1 &&TYPE( argv[0])==T_STRING) {
|
990
1076
|
log_message = argv[0];
|
991
|
-
VALUE re_str = rb_str_new2("^
|
1077
|
+
VALUE re_str = rb_str_new2("^PHP ([^:]+?)(?: error)?: {0,2}(.+) in (.+) on line (\\d+)$");
|
992
1078
|
VALUE re_option = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
|
993
1079
|
VALUE report_re = rb_funcall(rb_cRegexp, rb_intern("new"), 2, re_str, re_option);
|
994
1080
|
VALUE m = rb_funcall(argv[0], rb_intern("match"), 1, report_re);
|
@@ -1059,11 +1145,11 @@ void Init_php_vm()
|
|
1059
1145
|
php_vm_module_init();
|
1060
1146
|
atexit(php_vm_module_exit);
|
1061
1147
|
|
1062
|
-
zend_throw_exception_hook =
|
1148
|
+
zend_throw_exception_hook = php_vm_exception_hook;
|
1063
1149
|
|
1064
1150
|
// ini
|
1065
1151
|
zend_try {
|
1066
|
-
zend_alter_ini_entry("display_errors", sizeof("display_errors"), "
|
1152
|
+
zend_alter_ini_entry("display_errors", sizeof("display_errors"), "1", sizeof("0")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
|
1067
1153
|
zend_alter_ini_entry("log_errors", sizeof("log_errors"), "1", sizeof("1")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
|
1068
1154
|
} zend_catch {
|
1069
1155
|
} zend_end_try();
|
@@ -1085,7 +1171,7 @@ void Init_php_vm()
|
|
1085
1171
|
rb_define_singleton_method(rb_mPHPVM, "get_class", rb_php_vm_get_class, 1);
|
1086
1172
|
rb_define_singleton_method(rb_mPHPVM, "define_global", rb_php_vm_define_global, 0);
|
1087
1173
|
|
1088
|
-
rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.
|
1174
|
+
rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.3"));
|
1089
1175
|
|
1090
1176
|
rb_cv_set(rb_mPHPVM, "@@output_handler", Qnil);
|
1091
1177
|
rb_cv_set(rb_mPHPVM, "@@error_handler", Qnil);
|
@@ -1099,8 +1185,6 @@ void Init_php_vm()
|
|
1099
1185
|
rb_define_module_function(rb_mPHPGlobal, "print", rb_php_global_print, 1);
|
1100
1186
|
rb_define_module_function(rb_mPHPGlobal, "array", rb_php_global_array, -1);
|
1101
1187
|
|
1102
|
-
rb_php_vm_define_global(rb_mPHPVM);
|
1103
|
-
|
1104
1188
|
// class PHPVM::PHPClass
|
1105
1189
|
rb_cPHPClass = rb_define_class_under(rb_mPHPVM, "PHPClass", rb_cObject);
|
1106
1190
|
rb_define_class_variable(rb_cPHPClass, "@@classes", rb_obj_alloc(rb_cHash));
|
@@ -1135,4 +1219,6 @@ void Init_php_vm()
|
|
1135
1219
|
rb_define_method(rb_ePHPErrorReporting, "error_level", rb_php_error_reporting_error_level, 0);
|
1136
1220
|
rb_define_method(rb_ePHPErrorReporting, "file", rb_php_error_reporting_file, 0);
|
1137
1221
|
rb_define_method(rb_ePHPErrorReporting, "line", rb_php_error_reporting_line, 0);
|
1222
|
+
|
1223
|
+
rb_php_vm_define_global(rb_mPHPVM);
|
1138
1224
|
}
|
data/ext/php_vm/php_vm.h
CHANGED
@@ -77,6 +77,7 @@ extern VALUE rb_php_class_new(int argc, VALUE *argv, VALUE self);
|
|
77
77
|
extern VALUE rb_php_class_getter(VALUE self);
|
78
78
|
extern VALUE rb_php_class_setter(VALUE self, VALUE value);
|
79
79
|
extern VALUE rb_php_class_call(int argc, VALUE *argv, VALUE self);
|
80
|
+
extern VALUE rb_php_class_call_method_missing(int argc, VALUE *argv, VALUE self);
|
80
81
|
|
81
82
|
// class PHPVM::PHPObject
|
82
83
|
extern VALUE rb_php_object_initialize(VALUE self, VALUE class, VALUE arg_arr);
|
@@ -84,6 +85,7 @@ extern VALUE rb_php_object_php_class(VALUE self);
|
|
84
85
|
extern VALUE rb_php_object_getter(VALUE self);
|
85
86
|
extern VALUE rb_php_object_setter(VALUE self, VALUE value);
|
86
87
|
extern VALUE rb_php_object_call(int argc, VALUE *argv, VALUE self);
|
88
|
+
extern VALUE rb_php_object_call_method_missing(int argc, VALUE *argv, VALUE self);
|
87
89
|
|
88
90
|
// module
|
89
91
|
extern void php_vm_module_init();
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: php_vm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-31 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: php_vm is a native bridge between Ruby and PHP.
|
15
15
|
email:
|