php_vm 1.3.9 → 1.3.10

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 +104 -39
  2. data/ext/php_vm/php_vm.h +8 -3
  3. metadata +2 -2
data/ext/php_vm/php_vm.c CHANGED
@@ -18,14 +18,29 @@ VALUE rb_ePHPErrorReporting;
18
18
 
19
19
  // PHP Embed
20
20
 
21
+ static VALUE php_vm_handler_b_proc(HandlerArgs *args)
22
+ {
23
+ rb_proc_call(args->proc, args->args);
24
+ return Qnil;
25
+ }
26
+
27
+ static VALUE php_vm_handler_r_proc(HandlerArgs *args, VALUE e)
28
+ {
29
+ fprintf(stderr, "Exception has occurred in php_vm handler. php_vm handler must not occur exception.\n");
30
+ return Qnil;
31
+ }
32
+
21
33
  static int php_embed_output_handler(const char *str, unsigned int str_length TSRMLS_DC)
22
34
  {
23
35
  VALUE proc = rb_cv_get(rb_mPHPVM, "@@output_handler");
24
36
  if (rb_obj_is_kind_of(proc, rb_cProc)) {
25
37
  VALUE args = rb_ary_new();
26
38
  rb_ary_push(args, rb_str_new(str, str_length));
27
- rb_proc_call(proc, args);
28
- return str_length;
39
+
40
+ HandlerArgs handargs;
41
+ handargs.proc = proc;
42
+ handargs.args = args;
43
+ rb_rescue(php_vm_handler_b_proc, (VALUE)&handargs, php_vm_handler_r_proc, (VALUE)&handargs);
29
44
  } else {
30
45
  printf("%s", str);
31
46
  }
@@ -34,18 +49,19 @@ static int php_embed_output_handler(const char *str, unsigned int str_length TSR
34
49
 
35
50
  static void php_embed_error_handler(char *message TSRMLS_DC)
36
51
  {
37
- VALUE proc = rb_cv_get(rb_mPHPVM, "@@error_handler");
38
52
  VALUE report = rb_exc_new2(rb_ePHPErrorReporting, message);
53
+ VALUE proc = rb_cv_get(rb_mPHPVM, "@@error_handler");
39
54
  if (rb_obj_is_kind_of(proc, rb_cProc)) {
40
55
  VALUE args = rb_ary_new();
41
56
  rb_ary_push(args, report);
42
- rb_proc_call(proc, args);
43
- } else {
44
- if (rb_iv_get(report, "error_level")==ID2SYM(rb_intern("Fatal"))) {
45
- rb_exc_raise(report);
46
- } else {
47
- printf("%s\n", message);
48
- }
57
+
58
+ HandlerArgs handargs;
59
+ handargs.proc = proc;
60
+ handargs.args = args;
61
+ rb_rescue(php_vm_handler_b_proc, (VALUE)&handargs, php_vm_handler_r_proc, (VALUE)&handargs);
62
+ }
63
+ if (rb_funcall(report, rb_intern("error_level"), 0)==ID2SYM(rb_intern("Fatal"))) {
64
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", report);
49
65
  }
50
66
  }
51
67
 
@@ -60,13 +76,14 @@ static void php_vm_exception_hook(zval *ex TSRMLS_DC)
60
76
 
61
77
  // PHP
62
78
 
63
- void php_eval_string(char *code, int code_len TSRMLS_DC)
79
+ VALUE php_eval_string(char *code, int code_len, int use_retval TSRMLS_DC)
64
80
  {
65
81
  int syntax_error = 0;
82
+ zval retval;
66
83
 
67
84
  // eval
68
85
  zend_try {
69
- if (zend_eval_stringl(code, code_len, NULL, "php_vm" TSRMLS_CC)==FAILURE) {
86
+ if (zend_eval_stringl(code, code_len, (use_retval ? &retval : NULL), "php_vm" TSRMLS_CC)==FAILURE) {
70
87
  syntax_error = 1;
71
88
  }
72
89
  } zend_end_try();
@@ -89,8 +106,20 @@ void php_eval_string(char *code, int code_len TSRMLS_DC)
89
106
  int exit_status = EG(exit_status);
90
107
  EG(exit_status) = 0;
91
108
 
92
- rb_raise(rb_ePHPError, "exit status error: %d", exit_status);
109
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
110
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
111
+ if (report!=Qnil) {
112
+ rb_exc_raise(report);
113
+ } else {
114
+ rb_raise(rb_ePHPError, "exit status error: %d", exit_status);
115
+ }
116
+ }
117
+
118
+ // return
119
+ if (use_retval) {
120
+ return zval_to_value(&retval);
93
121
  }
122
+ return Qnil;
94
123
  }
95
124
 
96
125
  void find_zend_class_entry(char *name, int name_len, zend_class_entry ***ce TSRMLS_DC)
@@ -173,11 +202,15 @@ int new_php_object(zend_class_entry *ce, VALUE v_args, zval *retval TSRMLS_DC)
173
202
 
174
203
  // exception
175
204
  if (result==FAILURE) {
205
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
206
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
176
207
  if (g_exception) {
177
208
  VALUE exception = zval_to_value(g_exception);
178
209
  zval_ptr_dtor(&g_exception);
179
210
  g_exception = NULL;
180
211
  rb_exc_raise(exception);
212
+ } else if (report!=Qnil) {
213
+ rb_exc_raise(report);
181
214
  } else {
182
215
  rb_raise(rb_ePHPError, "Invocation of %s's constructor failed", ce->name);
183
216
  }
@@ -390,7 +423,7 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
390
423
  zval_ptr_dtor(&z_args);
391
424
 
392
425
  // result
393
- if (g_exception) {
426
+ if (g_exception || rb_cv_get(rb_mPHPVM, "@@last_error_reporting")!=Qnil) {
394
427
  result = FAILURE;
395
428
  }
396
429
  return result;
@@ -425,11 +458,15 @@ VALUE call_php_method_bridge(zend_class_entry *ce, zval *obj, zend_function *mpt
425
458
 
426
459
  // exception
427
460
  if (result==FAILURE) {
461
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
462
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
428
463
  if (g_exception) {
429
464
  VALUE exception = zval_to_value(g_exception);
430
465
  zval_ptr_dtor(&g_exception);
431
466
  g_exception = NULL;
432
467
  rb_exc_raise(exception);
468
+ } else if (report!=Qnil) {
469
+ rb_exc_raise(report);
433
470
  } else {
434
471
  rb_raise(rb_ePHPError, "raise exception: %s", mptr->common.function_name);
435
472
  }
@@ -600,7 +637,7 @@ VALUE rb_php_vm_set_error_handler(VALUE cls, VALUE proc)
600
637
  return Qnil;
601
638
  }
602
639
 
603
- void php_vm_require(char *token, VALUE filepath TSRMLS_DC)
640
+ VALUE php_vm_require(char *token, VALUE filepath TSRMLS_DC)
604
641
  {
605
642
  StringValue(filepath);
606
643
  filepath = rb_funcall(filepath, rb_intern("gsub"), 2, rb_str_new2("\\"), rb_str_new2("\\\\"));
@@ -611,41 +648,49 @@ void php_vm_require(char *token, VALUE filepath TSRMLS_DC)
611
648
  rb_str_cat(code, RSTRING_PTR(filepath), RSTRING_LEN(filepath));
612
649
  rb_str_cat2(code, "\";");
613
650
 
614
- php_eval_string(RSTRING_PTR(code), RSTRING_LEN(code) TSRMLS_CC);
651
+ VALUE retval = php_eval_string(RSTRING_PTR(code), RSTRING_LEN(code), 1 TSRMLS_CC);
652
+ switch (TYPE(retval)) {
653
+ case T_TRUE:
654
+ case T_FALSE:
655
+ case T_NIL:
656
+ break;
657
+ default:{
658
+ retval = rb_funcall(retval, rb_intern("to_i"), 0);
659
+ retval = rb_funcall(retval, rb_intern(">"), 1, INT2NUM(0));
660
+ break;
661
+ }
662
+ }
663
+ return retval==Qtrue ? Qtrue : Qfalse;
615
664
  }
616
665
 
617
666
  VALUE rb_php_vm_require(VALUE cls, VALUE filepath)
618
667
  {
619
668
  TSRMLS_FETCH();
620
- php_vm_require("require", filepath TSRMLS_CC);
621
- return Qtrue;
669
+ return php_vm_require("require", filepath TSRMLS_CC);
622
670
  }
623
671
 
624
672
  VALUE rb_php_vm_require_once(VALUE cls, VALUE filepath)
625
673
  {
626
674
  TSRMLS_FETCH();
627
- php_vm_require("require_once", filepath TSRMLS_CC);
628
- return Qtrue;
675
+ return php_vm_require("require_once", filepath TSRMLS_CC);
629
676
  }
630
677
 
631
678
  VALUE rb_php_vm_include(VALUE cls, VALUE filepath)
632
679
  {
633
680
  TSRMLS_FETCH();
634
- php_vm_require("include", filepath TSRMLS_CC);
635
- return Qnil;
681
+ return php_vm_require("include", filepath TSRMLS_CC);
636
682
  }
637
683
 
638
684
  VALUE rb_php_vm_include_once(VALUE cls, VALUE filepath)
639
685
  {
640
686
  TSRMLS_FETCH();
641
- php_vm_require("include_once", filepath TSRMLS_CC);
642
- return Qnil;
687
+ return php_vm_require("include_once", filepath TSRMLS_CC);
643
688
  }
644
689
 
645
690
  VALUE rb_php_vm_exec(VALUE cls, VALUE code)
646
691
  {
647
692
  TSRMLS_FETCH();
648
- php_eval_string(RSTRING_PTR(code), RSTRING_LEN(code) TSRMLS_CC);
693
+ php_eval_string(RSTRING_PTR(code), RSTRING_LEN(code), 0 TSRMLS_CC);
649
694
  return Qnil;
650
695
  }
651
696
 
@@ -673,6 +718,7 @@ VALUE define_global_constants()
673
718
  zval_ptr_dtor(&g_exception);
674
719
  g_exception = NULL;
675
720
  }
721
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
676
722
  return Qfalse;
677
723
  }
678
724
 
@@ -731,6 +777,7 @@ VALUE define_global_functions()
731
777
  zval_ptr_dtor(&g_exception);
732
778
  g_exception = NULL;
733
779
  }
780
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
734
781
  return Qfalse;
735
782
  }
736
783
 
@@ -775,6 +822,7 @@ VALUE define_global_classes()
775
822
  zval_ptr_dtor(&g_exception);
776
823
  g_exception = NULL;
777
824
  }
825
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
778
826
  return Qfalse;
779
827
  }
780
828
 
@@ -807,7 +855,7 @@ VALUE rb_php_vm_define_global(VALUE cls)
807
855
  VALUE res1 = define_global_constants();
808
856
  VALUE res2 = define_global_functions();
809
857
  VALUE res3 = define_global_classes();
810
- return res1==Qtrue && res2==Qtrue && res3==Qtrue;
858
+ return (res1==Qtrue && res2==Qtrue && res3==Qtrue) ? Qtrue : Qfalse;
811
859
  }
812
860
 
813
861
 
@@ -828,35 +876,31 @@ VALUE rb_php_global_class_call(VALUE self)
828
876
  static VALUE php_global_require_b_proc(RequireArgs *args)
829
877
  {
830
878
  TSRMLS_FETCH();
831
- php_vm_require(args->token, args->filepath TSRMLS_CC);
832
- return Qnil;
879
+ return php_vm_require(args->token, args->filepath TSRMLS_CC);
833
880
  }
834
881
 
835
882
  static VALUE php_global_require_r_proc(RequireArgs *args, VALUE e)
836
883
  {
837
- rb_funcall(Qnil, rb_intern("require"), 1, args->filepath);
838
- return Qnil;
884
+ return rb_funcall(Qnil, rb_intern("require"), 1, args->filepath);
839
885
  }
840
886
 
841
- void php_global_require(char *token, VALUE filepath)
887
+ VALUE php_global_require(char *token, VALUE filepath)
842
888
  {
843
889
  RequireArgs args;
844
890
  args.token = token;
845
891
  args.filepath = filepath;
846
892
 
847
- rb_rescue(php_global_require_b_proc, (VALUE)&args, php_global_require_r_proc, (VALUE)&args);
893
+ return rb_rescue(php_global_require_b_proc, (VALUE)&args, php_global_require_r_proc, (VALUE)&args);
848
894
  }
849
895
 
850
896
  VALUE rb_php_global_require(VALUE cls, VALUE filepath)
851
897
  {
852
- php_global_require("require", filepath);
853
- return Qtrue;
898
+ return php_global_require("require", filepath);
854
899
  }
855
900
 
856
901
  VALUE rb_php_global_require_once(VALUE cls, VALUE filepath)
857
902
  {
858
- php_global_require("require_once", filepath);
859
- return Qtrue;
903
+ return php_global_require("require_once", filepath);
860
904
  }
861
905
 
862
906
  VALUE rb_php_global_echo(int argc, VALUE *argv, VALUE cls)
@@ -1101,11 +1145,15 @@ VALUE rb_php_object_call_magic_clone(VALUE self)
1101
1145
  Z_SET_REFCOUNT_P(retval, 0);
1102
1146
  Z_SET_ISREF_P(retval);
1103
1147
 
1148
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
1149
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1104
1150
  if (g_exception) {
1105
1151
  VALUE exception = zval_to_value(g_exception);
1106
1152
  zval_ptr_dtor(&g_exception);
1107
1153
  g_exception = NULL;
1108
1154
  rb_exc_raise(exception);
1155
+ } else if (report!=Qnil) {
1156
+ rb_exc_raise(report);
1109
1157
  }
1110
1158
 
1111
1159
  return zval_to_value(retval);
@@ -1130,11 +1178,15 @@ VALUE rb_php_object_call_magic___get(VALUE self, VALUE name)
1130
1178
 
1131
1179
  zval_ptr_dtor(&member);
1132
1180
 
1181
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
1182
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1133
1183
  if (g_exception) {
1134
1184
  VALUE exception = zval_to_value(g_exception);
1135
1185
  zval_ptr_dtor(&g_exception);
1136
1186
  g_exception = NULL;
1137
1187
  rb_exc_raise(exception);
1188
+ } else if (report!=Qnil) {
1189
+ rb_exc_raise(report);
1138
1190
  }
1139
1191
 
1140
1192
  return zval_to_value(retval);
@@ -1162,11 +1214,15 @@ VALUE rb_php_object_call_magic___set(VALUE self, VALUE name, VALUE arg)
1162
1214
  zval_ptr_dtor(&member);
1163
1215
  zval_ptr_dtor(&z_arg);
1164
1216
 
1217
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
1218
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1165
1219
  if (g_exception) {
1166
1220
  VALUE exception = zval_to_value(g_exception);
1167
1221
  zval_ptr_dtor(&g_exception);
1168
1222
  g_exception = NULL;
1169
1223
  rb_exc_raise(exception);
1224
+ } else if (report!=Qnil) {
1225
+ rb_exc_raise(report);
1170
1226
  }
1171
1227
 
1172
1228
  return Qnil;
@@ -1190,11 +1246,15 @@ VALUE rb_php_object_call_magic___unset(VALUE self, VALUE name)
1190
1246
 
1191
1247
  zval_ptr_dtor(&member);
1192
1248
 
1249
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
1250
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1193
1251
  if (g_exception) {
1194
1252
  VALUE exception = zval_to_value(g_exception);
1195
1253
  zval_ptr_dtor(&g_exception);
1196
1254
  g_exception = NULL;
1197
1255
  rb_exc_raise(exception);
1256
+ } else if (report!=Qnil) {
1257
+ rb_exc_raise(report);
1198
1258
  }
1199
1259
 
1200
1260
  return Qnil;
@@ -1219,11 +1279,15 @@ VALUE rb_php_object_call_magic___isset(VALUE self, VALUE name)
1219
1279
 
1220
1280
  zval_ptr_dtor(&member);
1221
1281
 
1282
+ VALUE report = rb_cv_get(rb_mPHPVM, "@@last_error_reporting");
1283
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1222
1284
  if (g_exception) {
1223
1285
  VALUE exception = zval_to_value(g_exception);
1224
1286
  zval_ptr_dtor(&g_exception);
1225
1287
  g_exception = NULL;
1226
1288
  rb_exc_raise(exception);
1289
+ } else if (report!=Qnil) {
1290
+ rb_exc_raise(report);
1227
1291
  }
1228
1292
 
1229
1293
  return has ? Qtrue : Qfalse;
@@ -1304,7 +1368,7 @@ VALUE rb_php_error_reporting_initialize(int argc, VALUE *argv, VALUE self)
1304
1368
 
1305
1369
  if (argc==1 && TYPE(argv[0])==T_STRING) {
1306
1370
  log_message = argv[0];
1307
- VALUE re_str = rb_str_new2("^PHP ([^:]+?)(?: error)?: {0,2}(.+) in (.+) on line (\\d+)$");
1371
+ VALUE re_str = rb_str_new2("^(?:PHP )?([^:]+?)(?: error)?: {0,2}(.+) in (.+) on line (\\d+)$");
1308
1372
  VALUE re_option = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
1309
1373
  VALUE report_re = rb_funcall(rb_cRegexp, rb_intern("new"), 2, re_str, re_option);
1310
1374
  VALUE m = rb_funcall(argv[0], rb_intern("match"), 1, report_re);
@@ -1381,7 +1445,7 @@ void Init_php_vm()
1381
1445
 
1382
1446
  // ini
1383
1447
  zend_try {
1384
- zend_alter_ini_entry("display_errors", sizeof("display_errors"), "1", sizeof("0")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
1448
+ //zend_alter_ini_entry("display_errors", sizeof("display_errors"), "1", sizeof("0")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
1385
1449
  zend_alter_ini_entry("log_errors", sizeof("log_errors"), "1", sizeof("1")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
1386
1450
  } zend_catch {
1387
1451
  } zend_end_try();
@@ -1403,10 +1467,11 @@ void Init_php_vm()
1403
1467
  rb_define_singleton_method(rb_mPHPVM, "get_class", rb_php_vm_get_class, 1);
1404
1468
  rb_define_singleton_method(rb_mPHPVM, "define_global", rb_php_vm_define_global, 0);
1405
1469
 
1406
- rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.9"));
1470
+ rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.10"));
1407
1471
 
1408
1472
  rb_cv_set(rb_mPHPVM, "@@output_handler", Qnil);
1409
1473
  rb_cv_set(rb_mPHPVM, "@@error_handler", Qnil);
1474
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
1410
1475
 
1411
1476
  // module PHPVM::PHPGlobal
1412
1477
  rb_mPHPGlobal = rb_define_module_under(rb_mPHPVM, "PHPGlobal");
data/ext/php_vm/php_vm.h CHANGED
@@ -19,6 +19,11 @@ typedef struct {
19
19
  zval *zobj;
20
20
  } PHPNativeResource;
21
21
 
22
+ typedef struct {
23
+ VALUE proc;
24
+ VALUE args;
25
+ } HandlerArgs;
26
+
22
27
  typedef struct {
23
28
  char *token;
24
29
  VALUE filepath;
@@ -26,7 +31,7 @@ typedef struct {
26
31
 
27
32
 
28
33
  // PHP
29
- extern void php_eval_string(char *code, int code_len TSRMLS_DC);
34
+ extern VALUE php_eval_string(char *code, int code_len, int use_retval TSRMLS_DC);
30
35
  extern void find_zend_class_entry(char *name, int name_len, zend_class_entry ***ce TSRMLS_DC);
31
36
  extern int is_exception_zend_class_entry(zend_class_entry *ce TSRMLS_DC);
32
37
  extern int is_exception_zval(zval *z TSRMLS_DC);
@@ -53,7 +58,7 @@ extern VALUE rb_php_vm_get_output_handler(VALUE cls);
53
58
  extern VALUE rb_php_vm_set_output_handler(VALUE cls, VALUE proc);
54
59
  extern VALUE rb_php_vm_get_error_handler(VALUE cls);
55
60
  extern VALUE rb_php_vm_set_error_handler(VALUE cls, VALUE proc);
56
- extern void php_vm_require(char *token, VALUE filepath TSRMLS_DC);
61
+ extern VALUE php_vm_require(char *token, VALUE filepath TSRMLS_DC);
57
62
  extern VALUE rb_php_vm_require(VALUE cls, VALUE filepath);
58
63
  extern VALUE rb_php_vm_require_once(VALUE cls, VALUE filepath);
59
64
  extern VALUE rb_php_vm_include(VALUE cls, VALUE filepath);
@@ -68,7 +73,7 @@ extern VALUE rb_php_vm_define_global(VALUE cls);
68
73
  // module PHPVM::PHPGlobal
69
74
  extern VALUE rb_php_global_function_call(int argc, VALUE *argv, VALUE self);
70
75
  extern VALUE rb_php_global_class_call(VALUE self);
71
- extern void php_global_require(char *token, VALUE filepath);
76
+ extern VALUE php_global_require(char *token, VALUE filepath);
72
77
  extern VALUE rb_php_global_require(VALUE cls, VALUE filepath);
73
78
  extern VALUE rb_php_global_require_once(VALUE cls, VALUE filepath);
74
79
  extern VALUE rb_php_global_echo(int argc, VALUE *argv, VALUE cls);
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.9
4
+ version: 1.3.10
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: 2013-01-07 00:00:00.000000000 Z
12
+ date: 2013-01-08 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: php_vm is a native bridge between Ruby and PHP.
15
15
  email: