php_vm 1.3.9 → 1.3.10

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 +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: