php_vm 1.2.0 → 1.2.1

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.
Files changed (3) hide show
  1. data/ext/php_vm/php_vm.c +74 -21
  2. data/ext/php_vm/php_vm.h +1 -0
  3. metadata +2 -2
data/ext/php_vm/php_vm.c CHANGED
@@ -226,7 +226,7 @@ void define_php_methods(VALUE v_obj, zend_class_entry *ce, int is_static)
226
226
  }
227
227
  } else {
228
228
  // instance method
229
- if (strcmp("__construct", fname)==0) {
229
+ if (strcmp("__construct", fname)==0 || strcmp(ce->name, fname)==0) {
230
230
  // __construct => no define
231
231
 
232
232
  } else if (0==(flag & ZEND_ACC_STATIC)) {
@@ -243,16 +243,6 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
243
243
  {
244
244
  int result = FAILURE;
245
245
 
246
- // argv
247
- zval ***z_argv = malloc(sizeof(zval **) * argc);
248
- long i;
249
- for (i=0; i<argc; i++) {
250
- zval *tmp;
251
- MAKE_STD_ZVAL(tmp);
252
- value_to_zval(v_argv[i], tmp);
253
- z_argv[i] = &tmp;
254
- }
255
-
256
246
  // call info
257
247
  zend_fcall_info fci;
258
248
  zend_fcall_info_cache fcc;
@@ -265,9 +255,9 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
265
255
  fci.symbol_table = NULL;
266
256
  fci.object_ptr = obj;
267
257
  fci.retval_ptr_ptr = retval_ptr;
268
- fci.param_count = argc;
269
- fci.params = z_argv;
270
- fci.no_separation = 1;
258
+ fci.param_count = 0;
259
+ fci.params = NULL;
260
+ fci.no_separation = 0;
271
261
 
272
262
  fcc.initialized = 1;
273
263
  fcc.function_handler = mptr;
@@ -275,19 +265,49 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
275
265
  fcc.called_scope = ce ? ce : NULL;
276
266
  fcc.object_ptr = obj;
277
267
 
268
+ // zval args
269
+ zval *z_args;
270
+ MAKE_STD_ZVAL(z_args);
271
+ array_init(z_args);
272
+
273
+ long i;
274
+ for (i=0; i<argc; i++) {
275
+ zval *new_var;
276
+ MAKE_STD_ZVAL(new_var);
277
+ value_to_zval(v_argv[i], new_var);
278
+
279
+ zend_hash_next_index_insert(Z_ARRVAL_P(z_args), &new_var, sizeof(zval *), NULL);
280
+ }
281
+
282
+ zend_fcall_info_args(&fci, z_args);
283
+
278
284
  // call
279
285
  zend_try {
280
286
  result = zend_call_function(&fci, &fcc TSRMLS_CC);
281
287
  } zend_catch {
288
+ // EG(exception) is NULL... Why??
282
289
  //printf("call_php_method exception: %p\n", EG(exception));
283
290
  } zend_end_try();
284
291
 
285
- // release
286
- for (i=0; i<argc; i++) {
287
- zval_ptr_dtor(z_argv[i]);
292
+ // reference variable
293
+ HashPosition pos;
294
+ zval **arg;
295
+ zend_arg_info *arg_info = mptr->common.arg_info;
296
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z_args), &pos);
297
+ for (i=0; i<argc && i<mptr->common.num_args; i++) {
298
+ if (arg_info->pass_by_reference) {
299
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(z_args), (void *)&arg, &pos);
300
+ value_copy(v_argv[i], zval_to_value(*arg));
301
+ }
302
+ zend_hash_move_forward_ex(Z_ARRVAL_P(z_args), &pos);
303
+ arg_info++;
288
304
  }
289
- free(z_argv);
290
305
 
306
+ // release
307
+ for (i=0; i<fci.param_count; i++) {
308
+ zval_ptr_dtor(fci.params[i]);
309
+ }
310
+ zend_fcall_info_args_clear(&fci, 1);
291
311
  return result;
292
312
  }
293
313
 
@@ -299,9 +319,9 @@ VALUE backtrace_re;
299
319
  VALUE get_callee_name()
300
320
  {
301
321
  VALUE backtrace_arr = rb_funcall(rb_mKernel, rb_intern("caller"), 1, INT2NUM(0));
302
- if (backtrace_arr) {
322
+ if (backtrace_arr!=Qnil) {
303
323
  VALUE backtrace = rb_funcall(backtrace_arr, rb_intern("first"), 0);
304
- if (backtrace) {
324
+ if (backtrace!=Qnil) {
305
325
  VALUE m = rb_funcall(backtrace, rb_intern("match"), 1, backtrace_re);
306
326
  if (m!=Qnil) {
307
327
  return rb_funcall(m, rb_intern("[]"), 1, INT2NUM(3));
@@ -340,6 +360,7 @@ VALUE call_php_method_bridge(zend_class_entry *ce, zval *obj, VALUE callee, int
340
360
  rb_exc_raise(exception);
341
361
  }
342
362
  } else {
363
+ // accessor
343
364
  VALUE is_setter = rb_funcall(callee, rb_intern("end_with?"), 1, rb_str_new2("="));
344
365
 
345
366
  if (is_setter) {
@@ -375,6 +396,38 @@ VALUE call_php_method_bridge(zend_class_entry *ce, zval *obj, VALUE callee, int
375
396
  return zval_to_value(z_val);
376
397
  }
377
398
 
399
+ void value_copy(VALUE dst, VALUE src)
400
+ {
401
+ switch (TYPE(dst)) {
402
+ case T_ARRAY:{
403
+ if (TYPE(src)==T_ARRAY) {
404
+ rb_funcall(dst, rb_intern("replace"), 1, src);
405
+ } else {
406
+ rb_funcall(dst, rb_intern("clear"), 0);
407
+ rb_funcall(dst, rb_intern("<<"), 1, src);
408
+ }
409
+ break;
410
+ }
411
+ case T_HASH:{
412
+ rb_funcall(dst, rb_intern("clear"), 0);
413
+ if (TYPE(src)==T_HASH) {
414
+ rb_funcall(dst, rb_intern("update"), 1, src);
415
+ } else {
416
+ rb_funcall(dst, rb_intern("[]"), 2, rb_str_new2("reference"), src);
417
+ }
418
+ break;
419
+ }
420
+ case T_STRING:{
421
+ rb_funcall(dst, rb_intern("clear"), 0);
422
+ if (TYPE(src)!=T_STRING) {
423
+ src = rb_funcall(src, rb_intern("to_s"), 0);
424
+ }
425
+ rb_funcall(dst, rb_intern("concat"), 1, src);
426
+ break;
427
+ }
428
+ }
429
+ }
430
+
378
431
 
379
432
  // PHP Native resource
380
433
 
@@ -805,7 +858,7 @@ void Init_php_vm()
805
858
  rb_define_singleton_method(rb_mPHPVM, "define_global_classes", rb_php_vm_define_global_classes, 0);
806
859
  rb_define_singleton_method(rb_mPHPVM, "define_global", rb_php_vm_define_global, 0);
807
860
 
808
- rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.2.0"));
861
+ rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.2.1"));
809
862
 
810
863
  // module PHPVM::PHPGlobal
811
864
  rb_mPHPGlobal = rb_define_module_under(rb_mPHPVM, "PHPGlobal");
data/ext/php_vm/php_vm.h CHANGED
@@ -34,6 +34,7 @@ extern int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr,
34
34
  // Ruby
35
35
  extern VALUE get_callee_name();
36
36
  extern VALUE call_php_method_bridge(zend_class_entry *ce, zval *obj, VALUE callee, int argc, VALUE *argv);
37
+ extern void value_copy(VALUE dst, VALUE src);
37
38
 
38
39
  // PHP Native resource
39
40
  extern void php_native_resource_delete(PHPNativeResource *p);
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.2.0
4
+ version: 1.2.1
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-25 00:00:00.000000000 Z
12
+ date: 2012-12-26 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: php_vm is a native bridge between Ruby and PHP.
15
15
  email: