php_vm 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: