2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include <runtime/base/class_info.h>
18 #include <runtime/base/complex_types.h>
19 #include <runtime/ext/ext_string.h>
20 #include <runtime/ext/ext_network.h>
21 #include <runtime/ext/ext_soap.h>
22 #include <runtime/base/program_functions.h>
23 #include <system/gen/sys/system_globals.h>
27 ///////////////////////////////////////////////////////////////////////////////
28 // These are normally code-generated and we are implementing them here
29 // purely for unit testing.
32 ///////////////////////////////////////////////////////////////////////////////
34 // Used by test_ext_preg
35 static String
test_preg_rep(CStrRef a
, CStrRef b
, CStrRef c
) {
36 return concat(f_strtoupper(c
), a
);
39 #define CLASS_INFO_EMPTY_ENTRY "", NULL, NULL, NULL
40 #define METHOD_INFO_EMPTY_ENTRY NULL, NULL, NULL, NULL, NULL
42 const char *g_class_map
[] = {
43 /* header */ (const char *)ClassInfo::IsSystem
,
44 NULL
, CLASS_INFO_EMPTY_ENTRY
,
48 (const char *)ClassInfo::IsPublic
, "xbox_process_message",
49 METHOD_INFO_EMPTY_ENTRY
,
50 (const char *)ClassInfo::IsPublic
, "test", METHOD_INFO_EMPTY_ENTRY
,
51 (const char *)ClassInfo::IsPublic
, "lower", METHOD_INFO_EMPTY_ENTRY
,
52 (const char *)ClassInfo::IsPublic
, "sumlen_step", METHOD_INFO_EMPTY_ENTRY
,
53 (const char *)ClassInfo::IsPublic
, "sumlen_fini", METHOD_INFO_EMPTY_ENTRY
,
54 (const char *)ClassInfo::IsPublic
, "hello", METHOD_INFO_EMPTY_ENTRY
,
55 (const char *)ClassInfo::IsPublic
, "sub", METHOD_INFO_EMPTY_ENTRY
,
56 (const char *)ClassInfo::IsPublic
, "add", METHOD_INFO_EMPTY_ENTRY
,
57 (const char *)ClassInfo::IsPublic
, "sum", METHOD_INFO_EMPTY_ENTRY
,
58 (const char *)ClassInfo::IsPublic
, "fault", METHOD_INFO_EMPTY_ENTRY
,
59 (const char *)ClassInfo::IsPublic
, "strlen", METHOD_INFO_EMPTY_ENTRY
,
66 /* header */ (const char *)ClassInfo::IsNothing
,
67 NULL
, CLASS_INFO_EMPTY_ENTRY
,
77 /* header */ (const char *)ClassInfo::IsSystem
,
78 "test", CLASS_INFO_EMPTY_ENTRY
,
82 (const char *)ClassInfo::IsPublic
, "foo", METHOD_INFO_EMPTY_ENTRY
,
83 (const char *)ClassInfo::IsProtected
, "func", METHOD_INFO_EMPTY_ENTRY
,
84 (const char *)ClassInfo::IsPrivate
, "bar", METHOD_INFO_EMPTY_ENTRY
,
87 (const char *)ClassInfo::IsPublic
, "foo",
88 (const char *)ClassInfo::IsProtected
, "prop",
89 (const char *)ClassInfo::IsPrivate
, "bar",
92 "const_foo", (const char*)ClassInfo::IsInterface
, "s:1:\"f\";",
95 /* header */ (const char *)ClassInfo::IsInterface
,
96 "itestable", CLASS_INFO_EMPTY_ENTRY
,
100 (const char *)ClassInfo::IsPublic
, "foo", METHOD_INFO_EMPTY_ENTRY
,
101 (const char *)ClassInfo::IsPrivate
, "bar", METHOD_INFO_EMPTY_ENTRY
,
111 const char *g_source_root
= "";
112 const char *g_source_info
[] = { NULL
};
113 const char *g_source_cls2file
[] = { "test", "test_file", 0, NULL
};
114 const char *g_source_func2file
[] = { NULL
};
115 const char *g_paramrtti_map
[] = { NULL
};
117 Variant
get_class_var_init(CStrRef s
, const char *var
) {
121 Object
create_object_only(CStrRef s
, ObjectData
*root
/* = NULL */) {
122 return create_builtin_object_only(s
, root
);
125 ObjectData
*create_object_only_no_init(CStrRef s
, ObjectData
*root
) {
126 return create_builtin_object_only_no_init(s
, root
);
129 Variant
invokeImpl(void *extra
, CArrRef params
) {
130 const char *function
= (const char*)extra
;
131 // for TestExtFunction
132 if (strcasecmp(function
, "test") == 0) {
136 // for TestExtPreg::test_preg_replace_callback
137 if (strcasecmp(function
, "next_year") == 0) {
138 Array matches
= params
[0].toArray();
139 return matches
[1].toString() + String(matches
[2].toInt32() + 1);
142 // for TestExtArray::test_array_filter
143 if (strcasecmp(function
, "odd") == 0) {
144 return params
[0].toInt32() & 1;
146 if (strcasecmp(function
, "even") == 0) {
147 return !(params
[0].toInt32() & 1);
150 // for TestExtArray::test_array_map
151 if (strcasecmp(function
, "cube") == 0) {
152 int n
= params
[0].toInt32();
156 // for TestExtArray::test_array_multisort
157 if (strcasecmp(function
, "strtolower") == 0) {
158 return f_strtolower(params
[0]);
161 // for TestExtArray::test_array_reduce
162 if (strcasecmp(function
, "rsum") == 0) {
163 int v
= params
[0].toInt32();
164 int w
= params
[1].toInt32();
168 if (strcasecmp(function
, "rmul") == 0) {
169 int v
= params
[0].toInt32();
170 int w
= params
[1].toInt32();
175 // for TestExtArray::test_array_walk_recursive
176 if (strcasecmp(function
, "test_print") == 0) {
177 String item
= params
[0].toString();
178 String key
= params
[1].toString();
179 echo(key
+ ": " + item
+ "\n");
182 // for TestExtArray::test_array_walk
183 if (strcasecmp(function
, "test_alter") == 0) {
184 Variant
&item1
= lval(((Array
&)params
).lvalAt(0));
185 String key
= params
[1];
186 String prefix
= params
[2];
187 item1
= prefix
+ ": " + item1
;
190 // for TestExtArray::test_array_udiff
191 if (strcasecmp(function
, "comp_func") == 0) {
192 int n1
= params
[0].toInt32();
193 int n2
= params
[1].toInt32();
194 if (n1
== n2
) return 0;
195 return n1
> n2
? 1 : -1;
198 // for TestExtArray::test_usort
199 if (strcasecmp(function
, "reverse_comp_func") == 0) {
200 int n1
= params
[0].toInt32();
201 int n2
= params
[1].toInt32();
202 if (n1
== n2
) return 0;
203 return n1
> n2
? -1 : 1;
206 // for TestExtArray::test_array_uintersect
207 if (strcasecmp(function
, "strcasecmp") == 0) {
208 String s1
= params
[0].toString();
209 String s2
= params
[1].toString();
210 return strcasecmp(s1
.data(), s2
.data());
213 // for TestExtArray::test_uasort
214 if (strcasecmp(function
, "reverse_strcasecmp") == 0) {
215 String s1
= params
[0].toString();
216 String s2
= params
[1].toString();
217 return strcasecmp(s2
.data(), s1
.data());
221 if (strcasecmp(function
, "urltr") == 0) {
222 String s1
= params
[0].toString();
223 String s2
= params
[1].toString();
224 return String("url:") + s1
+ "=" + s2
;
227 // for TestExtCurl::test_curl_exec
228 if (strcasecmp(function
, "curl_write_func") == 0) {
229 print("curl_write_func called with ");
231 return params
[1].toString().size();
234 // for TestExtPreg::test_preg_replace
235 if (strcasecmp(function
, "strtoupper") == 0) {
236 return f_strtoupper(params
[0].toString());
238 if (strcasecmp(function
, "test_preg_rep") == 0) {
239 return test_preg_rep(params
[0].toString(), params
[1].toString(),
240 params
[2].toString());
242 if (strcasecmp(function
, "sprintf") == 0) {
243 return f_sprintf(params
.size(), params
[0],
244 params
.slice(1, params
.size() - 1, false));
247 // for TestExtSqlite3::test_sqlite3
248 if (strcasecmp(function
, "lower") == 0) {
249 return f_strtolower(params
[0]);
251 if (strcasecmp(function
, "sumlen_step") == 0) {
252 return params
[0].toInt64() + f_strlen(params
[2]);
254 if (strcasecmp(function
, "sumlen_fini") == 0) {
255 return params
[0].toInt64();
259 if (strcasecmp(function
, "hello") == 0) {
260 return "Hello World";
262 if (strcasecmp(function
, "add") == 0) {
263 return params
[0].toInt32() + params
[1].toInt32();
265 if (strcasecmp(function
, "sub") == 0) {
266 return params
[0].toInt32() - params
[1].toInt32();
268 if (strcasecmp(function
, "sum") == 0) {
270 for (ArrayIter
iter(params
[0]); iter
; ++iter
) {
271 sum
+= iter
.second().toInt32();
275 if (strcasecmp(function
, "strlen") == 0) {
276 return f_strlen(params
[0]);
278 if (strcasecmp(function
, "fault") == 0) {
279 return Object((NEWOBJ(c_SoapFault
)())->create("MyFault","My fault string"));
283 if (strcasecmp(function
, "xbox_process_message") == 0) {
284 return StringUtil::Reverse(params
[0]);
289 CallInfo
invokeImplCallInfo((void*)invokeImpl
, NULL
, 0, CallInfo::VarArgs
, 0);
290 bool get_call_info(const CallInfo
*&ci
, void *&extra
, const char *s
,
291 int64 hash
/* = -1 */) {
292 if (!strcasecmp(s
, "nontest")) {
298 ci
= &invokeImplCallInfo
;
302 bool get_call_info_no_eval(const CallInfo
*&ci
, void *&extra
, const char *s
,
303 int64 hash
/* = -1 */) {
304 return get_call_info(ci
, extra
, s
, hash
);
307 void init_static_variables() { SystemScalarArrays::initialize();}
309 class GlobalVariables
: public SystemGlobals
{};
310 static IMPLEMENT_THREAD_LOCAL(GlobalVariables
, g_variables
);
311 GlobalVariables
*get_global_variables_check() { return NULL
;}
312 GlobalVariables
*get_global_variables() { return g_variables
.get();}
313 LVariableTable
*get_variable_table() { return g_variables
.get(); }
314 Globals
*get_globals() { return g_variables
.get(); }
315 SystemGlobals
*get_system_globals() { return g_variables
.get(); }
316 void init_global_variables() {
317 GlobalVariables
*g
= get_global_variables();
318 ThreadInfo::s_threadInfo
->m_globals
= g
;
321 void free_global_variables() { g_variables
.destroy();}
322 void init_literal_varstrings() {}
323 bool has_eval_support
= true;
324 Variant
invoke_file(CStrRef path
, bool once
/* = false */,
325 LVariableTable
* variables
/* = NULL */,
326 const char *currentDir
/* = NULL */) {
327 String cmd
= canonicalize_path(path
, "", 0);
328 if (path
== "string") {
329 echo("Hello, world!");
332 if (cmd
== "pageletserver") {
333 SystemGlobals
*g
= (SystemGlobals
*)get_global_variables();
335 echo("pagelet postparam: ");
336 echo(g
->GV(HTTP_RAW_POST_DATA
));
337 echo("pagelet getparam: ");
338 echo(g
->GV(_GET
)["getparam"]);
339 echo("pagelet header: ");
340 echo(g
->GV(_SERVER
)["HTTP_MYHEADER"]);
341 f_header("ResponseHeader: okay");
343 sleep(1); // give status check time to happen
349 Variant
get_static_property(CStrRef s
, const char *prop
) {
352 Variant
get_constant(CStrRef name
, bool error
) {
355 Variant
get_class_constant(CStrRef s
, const char *prop
,
356 int fatal
/* = true */) {
360 Array
get_global_array_wrapper() {
364 Variant
*get_static_property_lv(CStrRef s
, const char *prop
) {
368 bool get_call_info_static_method(MethodCallPackage
&info
) {
372 const ObjectStaticCallbacks
* get_object_static_callbacks(CStrRef s
) {
376 void fiber_marshal_global_state(GlobalVariables
*g1
, GlobalVariables
*g2
,
377 FiberReferenceMap
&refMap
) {
380 void fiber_unmarshal_global_state(GlobalVariables
*g1
, GlobalVariables
*g2
,
381 FiberReferenceMap
&refMap
,
383 const vector
<pair
<string
, char> > &resolver
){
386 Array
get_global_state() { return Array(); }
388 ///////////////////////////////////////////////////////////////////////////////