Index: trunk/php/luasandbox/luasandbox.c |
— | — | @@ -1038,10 +1038,12 @@ |
1039 | 1039 | * each value is a corresponding PHP callback. |
1040 | 1040 | * |
1041 | 1041 | * Both Lua and PHP allow functions to be called with any number of arguments. |
1042 | | - * The parameters to the Lua function will be passed through to the PHP. A |
1043 | | - * single value will always be returned to Lua, which is the return value from |
1044 | | - * the PHP function. If the PHP function does not return any value, Lua will |
1045 | | - * see a return value of nil. |
| 1042 | + * The parameters to the Lua function will be passed through to the PHP. |
| 1043 | + * |
| 1044 | + * Lua supports multiple return values. The PHP function should return either |
| 1045 | + * null (for zero return values) or an array of return values. The keys of the |
| 1046 | + * return array will not be used, rather the values will be taken in their |
| 1047 | + * internal order. |
1046 | 1048 | */ |
1047 | 1049 | PHP_METHOD(LuaSandbox, registerLibrary) |
1048 | 1050 | { |
— | — | @@ -1136,6 +1138,7 @@ |
1137 | 1139 | zval **pointers; |
1138 | 1140 | zval ***double_pointers; |
1139 | 1141 | int num_results = 0; |
| 1142 | + Bucket *bucket; |
1140 | 1143 | TSRMLS_FETCH(); |
1141 | 1144 | |
1142 | 1145 | // Based on zend_parse_arg_impl() |
— | — | @@ -1173,9 +1176,20 @@ |
1174 | 1177 | if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS |
1175 | 1178 | && fci.retval_ptr_ptr && *fci.retval_ptr_ptr) |
1176 | 1179 | { |
1177 | | - // Push the return value back to Lua |
1178 | | - luasandbox_push_zval(L, *fci.retval_ptr_ptr); |
1179 | | - num_results = 1; |
| 1180 | + // Push the return values back to Lua |
| 1181 | + if (Z_TYPE_PP(fci.retval_ptr_ptr) == IS_NULL) { |
| 1182 | + // No action |
| 1183 | + } else if (Z_TYPE_PP(fci.retval_ptr_ptr) == IS_ARRAY) { |
| 1184 | + bucket = Z_ARRVAL_PP(fci.retval_ptr_ptr)->pListHead; |
| 1185 | + while (bucket) { |
| 1186 | + luasandbox_push_zval(L, *((zval **)bucket->pData)); |
| 1187 | + bucket = bucket->pListNext; |
| 1188 | + num_results++; |
| 1189 | + } |
| 1190 | + } else { |
| 1191 | + php_error_docref(NULL TSRMLS_CC, E_WARNING, |
| 1192 | + "function tried to return a single value to Lua without wrapping it in an array"); |
| 1193 | + } |
1180 | 1194 | zval_ptr_dtor(&retval_ptr); |
1181 | 1195 | } |
1182 | 1196 | |
Index: trunk/php/luasandbox/tests/invalid_state.phpt |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | $dump = $f->dump(); |
10 | 10 | try { |
11 | 11 | $f->call(); |
12 | | -} catch (LuaSandboxEmergencyTimeout $e) { |
| 12 | +} catch (LuaSandboxEmergencyTimeoutError $e) { |
13 | 13 | print $e->getMessage() . "\n"; |
14 | 14 | } |
15 | 15 | $f->call(); |
Index: trunk/php/luasandbox/tests/reentrant.phpt |
— | — | @@ -23,14 +23,14 @@ |
24 | 24 | function factorial($n) { |
25 | 25 | global $luaFactorial; |
26 | 26 | if ($n <= 1) { |
27 | | - return 1; |
| 27 | + return array(1); |
28 | 28 | } else { |
29 | 29 | $ret = $luaFactorial->call($n - 1); |
30 | | - return $n * $ret[0]; |
| 30 | + return array($n * $ret[0]); |
31 | 31 | } |
32 | 32 | } |
33 | 33 | |
34 | | -print factorial(10) . "\n"; |
| 34 | +print implode('', factorial(10)) . "\n"; |
35 | 35 | var_dump( $luaFactorial->call(10) ); |
36 | 36 | |
37 | 37 | try { |