zend.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Andi Gutmans <andi@php.net> |
  16. | Zeev Suraski <zeev@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "zend.h"
  20. #include "zend_extensions.h"
  21. #include "zend_modules.h"
  22. #include "zend_constants.h"
  23. #include "zend_list.h"
  24. #include "zend_API.h"
  25. #include "zend_exceptions.h"
  26. #include "zend_builtin_functions.h"
  27. #include "zend_ini.h"
  28. #include "zend_vm.h"
  29. #include "zend_dtrace.h"
  30. #include "zend_virtual_cwd.h"
  31. #include "zend_smart_str.h"
  32. #include "zend_smart_string.h"
  33. #include "zend_cpuinfo.h"
  34. #include "zend_attributes.h"
  35. #include "zend_observer.h"
  36. #include "zend_fibers.h"
  37. #include "Optimizer/zend_optimizer.h"
  38. static size_t global_map_ptr_last = 0;
  39. static bool startup_done = false;
  40. #ifdef ZTS
  41. ZEND_API int compiler_globals_id;
  42. ZEND_API int executor_globals_id;
  43. ZEND_API size_t compiler_globals_offset;
  44. ZEND_API size_t executor_globals_offset;
  45. static HashTable *global_function_table = NULL;
  46. static HashTable *global_class_table = NULL;
  47. static HashTable *global_constants_table = NULL;
  48. static HashTable *global_auto_globals_table = NULL;
  49. static HashTable *global_persistent_list = NULL;
  50. TSRMLS_MAIN_CACHE_DEFINE()
  51. # define GLOBAL_FUNCTION_TABLE global_function_table
  52. # define GLOBAL_CLASS_TABLE global_class_table
  53. # define GLOBAL_CONSTANTS_TABLE global_constants_table
  54. # define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
  55. #else
  56. # define GLOBAL_FUNCTION_TABLE CG(function_table)
  57. # define GLOBAL_CLASS_TABLE CG(class_table)
  58. # define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
  59. # define GLOBAL_CONSTANTS_TABLE EG(zend_constants)
  60. #endif
  61. ZEND_API zend_utility_values zend_uv;
  62. ZEND_API bool zend_dtrace_enabled;
  63. /* version information */
  64. static char *zend_version_info;
  65. static uint32_t zend_version_info_length;
  66. #define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n"
  67. #define PRINT_ZVAL_INDENT 4
  68. /* true multithread-shared globals */
  69. ZEND_API zend_class_entry *zend_standard_class_def = NULL;
  70. ZEND_API size_t (*zend_printf)(const char *format, ...);
  71. ZEND_API zend_write_func_t zend_write;
  72. ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
  73. ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
  74. ZEND_API void (*zend_ticks_function)(int ticks);
  75. ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
  76. ZEND_API void (*zend_error_cb)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
  77. void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
  78. void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
  79. ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
  80. ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
  81. ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
  82. ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
  83. /* This callback must be signal handler safe! */
  84. void (*zend_on_timeout)(int seconds);
  85. static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
  86. static zval *(*zend_get_configuration_directive_p)(zend_string *name);
  87. #if ZEND_RC_DEBUG
  88. ZEND_API bool zend_rc_debug = 0;
  89. #endif
  90. static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
  91. {
  92. if (!new_value) {
  93. EG(error_reporting) = E_ALL;
  94. } else {
  95. EG(error_reporting) = atoi(ZSTR_VAL(new_value));
  96. }
  97. return SUCCESS;
  98. }
  99. /* }}} */
  100. static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
  101. {
  102. bool val;
  103. val = zend_ini_parse_bool(new_value);
  104. gc_enable(val);
  105. return SUCCESS;
  106. }
  107. /* }}} */
  108. static ZEND_INI_DISP(zend_gc_enabled_displayer_cb) /* {{{ */
  109. {
  110. if (gc_enabled()) {
  111. ZEND_PUTS("On");
  112. } else {
  113. ZEND_PUTS("Off");
  114. }
  115. }
  116. /* }}} */
  117. static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
  118. {
  119. if (!CG(multibyte)) {
  120. return FAILURE;
  121. }
  122. if (!zend_multibyte_get_functions()) {
  123. return SUCCESS;
  124. }
  125. return zend_multibyte_set_script_encoding_by_string(new_value ? ZSTR_VAL(new_value) : NULL, new_value ? ZSTR_LEN(new_value) : 0);
  126. }
  127. /* }}} */
  128. static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
  129. {
  130. zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
  131. zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
  132. if (stage != ZEND_INI_STAGE_STARTUP &&
  133. stage != ZEND_INI_STAGE_SHUTDOWN &&
  134. *p != val &&
  135. (*p < 0 || val < 0)) {
  136. zend_error(E_WARNING, "zend.assertions may be completely enabled or disabled only in php.ini");
  137. return FAILURE;
  138. }
  139. *p = val;
  140. return SUCCESS;
  141. }
  142. /* }}} */
  143. static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
  144. {
  145. zend_long i = ZEND_ATOL(ZSTR_VAL(new_value));
  146. if (i >= 0 && i <= 1000000) {
  147. EG(exception_string_param_max_len) = i;
  148. return SUCCESS;
  149. } else {
  150. return FAILURE;
  151. }
  152. }
  153. /* }}} */
  154. static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */
  155. {
  156. if (new_value) {
  157. EG(fiber_stack_size) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
  158. } else {
  159. EG(fiber_stack_size) = ZEND_FIBER_DEFAULT_C_STACK_SIZE;
  160. }
  161. return SUCCESS;
  162. }
  163. /* }}} */
  164. #if ZEND_DEBUG
  165. # define SIGNAL_CHECK_DEFAULT "1"
  166. #else
  167. # define SIGNAL_CHECK_DEFAULT "0"
  168. #endif
  169. ZEND_INI_BEGIN()
  170. ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
  171. STD_ZEND_INI_ENTRY("zend.assertions", "1", ZEND_INI_ALL, OnUpdateAssertions, assertions, zend_executor_globals, executor_globals)
  172. ZEND_INI_ENTRY3_EX("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, NULL, NULL, NULL, zend_gc_enabled_displayer_cb)
  173. STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals)
  174. ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding)
  175. STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
  176. #ifdef ZEND_SIGNALS
  177. STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
  178. #endif
  179. STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
  180. STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals)
  181. STD_ZEND_INI_ENTRY("fiber.stack_size", NULL, ZEND_INI_ALL, OnUpdateFiberStackSize, fiber_stack_size, zend_executor_globals, executor_globals)
  182. ZEND_INI_END()
  183. ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
  184. {
  185. smart_string buf = {0};
  186. /* since there are places where (v)spprintf called without checking for null,
  187. a bit of defensive coding here */
  188. if (!pbuf) {
  189. return 0;
  190. }
  191. zend_printf_to_smart_string(&buf, format, ap);
  192. if (max_len && buf.len > max_len) {
  193. buf.len = max_len;
  194. }
  195. smart_string_0(&buf);
  196. if (buf.c) {
  197. *pbuf = buf.c;
  198. return buf.len;
  199. } else {
  200. *pbuf = estrndup("", 0);
  201. return 0;
  202. }
  203. }
  204. /* }}} */
  205. ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) /* {{{ */
  206. {
  207. va_list arg;
  208. size_t len;
  209. va_start(arg, format);
  210. len = zend_vspprintf(message, max_len, format, arg);
  211. va_end(arg);
  212. return len;
  213. }
  214. /* }}} */
  215. ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...) /* {{{ */
  216. {
  217. va_list arg;
  218. size_t len;
  219. va_start(arg, format);
  220. len = zend_vspprintf(message, max_len, format, arg);
  221. va_end(arg);
  222. return len;
  223. }
  224. /* }}} */
  225. ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
  226. {
  227. smart_str buf = {0};
  228. zend_printf_to_smart_str(&buf, format, ap);
  229. if (!buf.s) {
  230. return ZSTR_EMPTY_ALLOC();
  231. }
  232. if (max_len && ZSTR_LEN(buf.s) > max_len) {
  233. ZSTR_LEN(buf.s) = max_len;
  234. }
  235. smart_str_0(&buf);
  236. return buf.s;
  237. }
  238. /* }}} */
  239. ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /* {{{ */
  240. {
  241. va_list arg;
  242. zend_string *str;
  243. va_start(arg, format);
  244. str = zend_vstrpprintf(max_len, format, arg);
  245. va_end(arg);
  246. return str;
  247. }
  248. /* }}} */
  249. ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...) /* {{{ */
  250. {
  251. va_list arg;
  252. zend_string *str;
  253. va_start(arg, format);
  254. str = zend_vstrpprintf(max_len, format, arg);
  255. va_end(arg);
  256. return str;
  257. }
  258. /* }}} */
  259. static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent);
  260. static void print_hash(smart_str *buf, HashTable *ht, int indent, bool is_object) /* {{{ */
  261. {
  262. zval *tmp;
  263. zend_string *string_key;
  264. zend_ulong num_key;
  265. int i;
  266. for (i = 0; i < indent; i++) {
  267. smart_str_appendc(buf, ' ');
  268. }
  269. smart_str_appends(buf, "(\n");
  270. indent += PRINT_ZVAL_INDENT;
  271. ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
  272. for (i = 0; i < indent; i++) {
  273. smart_str_appendc(buf, ' ');
  274. }
  275. smart_str_appendc(buf, '[');
  276. if (string_key) {
  277. if (is_object) {
  278. const char *prop_name, *class_name;
  279. size_t prop_len;
  280. int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
  281. smart_str_appendl(buf, prop_name, prop_len);
  282. if (class_name && mangled == SUCCESS) {
  283. if (class_name[0] == '*') {
  284. smart_str_appends(buf, ":protected");
  285. } else {
  286. smart_str_appends(buf, ":");
  287. smart_str_appends(buf, class_name);
  288. smart_str_appends(buf, ":private");
  289. }
  290. }
  291. } else {
  292. smart_str_append(buf, string_key);
  293. }
  294. } else {
  295. smart_str_append_long(buf, num_key);
  296. }
  297. smart_str_appends(buf, "] => ");
  298. zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT);
  299. smart_str_appends(buf, "\n");
  300. } ZEND_HASH_FOREACH_END();
  301. indent -= PRINT_ZVAL_INDENT;
  302. for (i = 0; i < indent; i++) {
  303. smart_str_appendc(buf, ' ');
  304. }
  305. smart_str_appends(buf, ")\n");
  306. }
  307. /* }}} */
  308. static void print_flat_hash(smart_str *buf, HashTable *ht) /* {{{ */
  309. {
  310. zval *tmp;
  311. zend_string *string_key;
  312. zend_ulong num_key;
  313. int i = 0;
  314. ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
  315. if (i++ > 0) {
  316. smart_str_appendc(buf, ',');
  317. }
  318. smart_str_appendc(buf, '[');
  319. if (string_key) {
  320. smart_str_append(buf, string_key);
  321. } else {
  322. smart_str_append_unsigned(buf, num_key);
  323. }
  324. smart_str_appends(buf, "] => ");
  325. zend_print_flat_zval_r_to_buf(buf, tmp);
  326. } ZEND_HASH_FOREACH_END();
  327. }
  328. /* }}} */
  329. ZEND_API bool zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
  330. {
  331. if (Z_TYPE_P(expr) == IS_STRING) {
  332. return 0;
  333. } else {
  334. ZVAL_STR(expr_copy, zval_get_string_func(expr));
  335. return 1;
  336. }
  337. }
  338. /* }}} */
  339. ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
  340. {
  341. zend_string *tmp_str;
  342. zend_string *str = zval_get_tmp_string(expr, &tmp_str);
  343. size_t len = ZSTR_LEN(str);
  344. if (len != 0) {
  345. zend_write(ZSTR_VAL(str), len);
  346. }
  347. zend_tmp_string_release(tmp_str);
  348. return len;
  349. }
  350. /* }}} */
  351. void zend_print_flat_zval_r_to_buf(smart_str *buf, zval *expr) /* {{{ */
  352. {
  353. switch (Z_TYPE_P(expr)) {
  354. case IS_ARRAY:
  355. smart_str_appends(buf, "Array (");
  356. if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
  357. if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
  358. smart_str_appends(buf, " *RECURSION*");
  359. return;
  360. }
  361. GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
  362. }
  363. print_flat_hash(buf, Z_ARRVAL_P(expr));
  364. smart_str_appendc(buf, ')');
  365. GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
  366. break;
  367. case IS_OBJECT:
  368. {
  369. HashTable *properties;
  370. zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
  371. smart_str_append(buf, class_name);
  372. smart_str_appends(buf, " Object (");
  373. zend_string_release_ex(class_name, 0);
  374. if (GC_IS_RECURSIVE(Z_COUNTED_P(expr))) {
  375. smart_str_appends(buf, " *RECURSION*");
  376. return;
  377. }
  378. properties = Z_OBJPROP_P(expr);
  379. if (properties) {
  380. GC_PROTECT_RECURSION(Z_OBJ_P(expr));
  381. print_flat_hash(buf, properties);
  382. GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
  383. }
  384. smart_str_appendc(buf, ')');
  385. break;
  386. }
  387. case IS_REFERENCE:
  388. zend_print_flat_zval_r_to_buf(buf, Z_REFVAL_P(expr));
  389. break;
  390. case IS_STRING:
  391. smart_str_append(buf, Z_STR_P(expr));
  392. break;
  393. default:
  394. {
  395. zend_string *str = zval_get_string_func(expr);
  396. smart_str_append(buf, str);
  397. zend_string_release_ex(str, 0);
  398. break;
  399. }
  400. }
  401. }
  402. /* }}} */
  403. ZEND_API void zend_print_flat_zval_r(zval *expr)
  404. {
  405. smart_str buf = {0};
  406. zend_print_flat_zval_r_to_buf(&buf, expr);
  407. smart_str_0(&buf);
  408. zend_write(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
  409. smart_str_free(&buf);
  410. }
  411. static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* {{{ */
  412. {
  413. switch (Z_TYPE_P(expr)) {
  414. case IS_ARRAY:
  415. smart_str_appends(buf, "Array\n");
  416. if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
  417. if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
  418. smart_str_appends(buf, " *RECURSION*");
  419. return;
  420. }
  421. GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
  422. }
  423. print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
  424. GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
  425. break;
  426. case IS_OBJECT:
  427. {
  428. HashTable *properties;
  429. zend_object *zobj = Z_OBJ_P(expr);
  430. zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(zobj);
  431. smart_str_appends(buf, ZSTR_VAL(class_name));
  432. zend_string_release_ex(class_name, 0);
  433. if (!(zobj->ce->ce_flags & ZEND_ACC_ENUM)) {
  434. smart_str_appends(buf, " Object\n");
  435. } else {
  436. smart_str_appends(buf, " Enum");
  437. if (zobj->ce->enum_backing_type != IS_UNDEF) {
  438. smart_str_appendc(buf, ':');
  439. smart_str_appends(buf, zend_get_type_by_const(zobj->ce->enum_backing_type));
  440. }
  441. smart_str_appendc(buf, '\n');
  442. }
  443. if (GC_IS_RECURSIVE(Z_OBJ_P(expr))) {
  444. smart_str_appends(buf, " *RECURSION*");
  445. return;
  446. }
  447. if ((properties = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_DEBUG)) == NULL) {
  448. break;
  449. }
  450. GC_PROTECT_RECURSION(Z_OBJ_P(expr));
  451. print_hash(buf, properties, indent, 1);
  452. GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
  453. zend_release_properties(properties);
  454. break;
  455. }
  456. case IS_LONG:
  457. smart_str_append_long(buf, Z_LVAL_P(expr));
  458. break;
  459. case IS_REFERENCE:
  460. zend_print_zval_r_to_buf(buf, Z_REFVAL_P(expr), indent);
  461. break;
  462. case IS_STRING:
  463. smart_str_append(buf, Z_STR_P(expr));
  464. break;
  465. default:
  466. {
  467. zend_string *str = zval_get_string_func(expr);
  468. smart_str_append(buf, str);
  469. zend_string_release_ex(str, 0);
  470. }
  471. break;
  472. }
  473. }
  474. /* }}} */
  475. ZEND_API zend_string *zend_print_zval_r_to_str(zval *expr, int indent) /* {{{ */
  476. {
  477. smart_str buf = {0};
  478. zend_print_zval_r_to_buf(&buf, expr, indent);
  479. smart_str_0(&buf);
  480. return buf.s;
  481. }
  482. /* }}} */
  483. ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
  484. {
  485. zend_string *str = zend_print_zval_r_to_str(expr, indent);
  486. zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
  487. zend_string_release_ex(str, 0);
  488. }
  489. /* }}} */
  490. static FILE *zend_fopen_wrapper(zend_string *filename, zend_string **opened_path) /* {{{ */
  491. {
  492. if (opened_path) {
  493. *opened_path = zend_string_copy(filename);
  494. }
  495. return fopen(ZSTR_VAL(filename), "rb");
  496. }
  497. /* }}} */
  498. #ifdef ZTS
  499. static bool short_tags_default = 1;
  500. static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
  501. #else
  502. # define short_tags_default 1
  503. # define compiler_options_default ZEND_COMPILE_DEFAULT
  504. #endif
  505. static void zend_set_default_compile_time_values(void) /* {{{ */
  506. {
  507. /* default compile-time values */
  508. CG(short_tags) = short_tags_default;
  509. CG(compiler_options) = compiler_options_default;
  510. CG(rtd_key_counter) = 0;
  511. }
  512. /* }}} */
  513. #ifdef ZEND_WIN32
  514. static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
  515. {
  516. ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
  517. osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  518. if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
  519. ZEND_UNREACHABLE(); /* Should not happen as sizeof is used. */
  520. }
  521. }
  522. /* }}} */
  523. #endif
  524. static void zend_init_exception_op(void) /* {{{ */
  525. {
  526. memset(EG(exception_op), 0, sizeof(EG(exception_op)));
  527. EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
  528. ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
  529. EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
  530. ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
  531. EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
  532. ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
  533. }
  534. /* }}} */
  535. static void zend_init_call_trampoline_op(void) /* {{{ */
  536. {
  537. memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
  538. EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
  539. ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
  540. }
  541. /* }}} */
  542. static void auto_global_dtor(zval *zv) /* {{{ */
  543. {
  544. free(Z_PTR_P(zv));
  545. }
  546. /* }}} */
  547. #ifdef ZTS
  548. static void function_copy_ctor(zval *zv) /* {{{ */
  549. {
  550. zend_function *old_func = Z_FUNC_P(zv);
  551. zend_function *func;
  552. if (old_func->type == ZEND_USER_FUNCTION) {
  553. ZEND_ASSERT(old_func->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
  554. return;
  555. }
  556. func = pemalloc(sizeof(zend_internal_function), 1);
  557. Z_FUNC_P(zv) = func;
  558. memcpy(func, old_func, sizeof(zend_internal_function));
  559. function_add_ref(func);
  560. if ((old_func->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))
  561. && old_func->common.arg_info) {
  562. uint32_t i;
  563. uint32_t num_args = old_func->common.num_args + 1;
  564. zend_arg_info *arg_info = old_func->common.arg_info - 1;
  565. zend_arg_info *new_arg_info;
  566. if (old_func->common.fn_flags & ZEND_ACC_VARIADIC) {
  567. num_args++;
  568. }
  569. new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1);
  570. memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
  571. for (i = 0 ; i < num_args; i++) {
  572. if (ZEND_TYPE_HAS_LIST(arg_info[i].type)) {
  573. zend_type_list *old_list = ZEND_TYPE_LIST(arg_info[i].type);
  574. zend_type_list *new_list = pemalloc(ZEND_TYPE_LIST_SIZE(old_list->num_types), 1);
  575. memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
  576. ZEND_TYPE_SET_PTR(new_arg_info[i].type, new_list);
  577. zend_type *list_type;
  578. ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
  579. zend_string *name = zend_string_dup(ZEND_TYPE_NAME(*list_type), 1);
  580. ZEND_TYPE_SET_PTR(*list_type, name);
  581. } ZEND_TYPE_LIST_FOREACH_END();
  582. } else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) {
  583. zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
  584. ZEND_TYPE_SET_PTR(new_arg_info[i].type, name);
  585. }
  586. }
  587. func->common.arg_info = new_arg_info + 1;
  588. }
  589. if (old_func->common.attributes) {
  590. zend_attribute *old_attr;
  591. func->common.attributes = NULL;
  592. ZEND_HASH_FOREACH_PTR(old_func->common.attributes, old_attr) {
  593. uint32_t i;
  594. zend_attribute *attr;
  595. attr = zend_add_attribute(&func->common.attributes, old_attr->name, old_attr->argc, old_attr->flags, old_attr->offset, old_attr->lineno);
  596. for (i = 0 ; i < old_attr->argc; i++) {
  597. ZVAL_DUP(&attr->args[i].value, &old_attr->args[i].value);
  598. }
  599. } ZEND_HASH_FOREACH_END();
  600. }
  601. }
  602. /* }}} */
  603. static void auto_global_copy_ctor(zval *zv) /* {{{ */
  604. {
  605. zend_auto_global *old_ag = (zend_auto_global *) Z_PTR_P(zv);
  606. zend_auto_global *new_ag = pemalloc(sizeof(zend_auto_global), 1);
  607. new_ag->name = old_ag->name;
  608. new_ag->auto_global_callback = old_ag->auto_global_callback;
  609. new_ag->jit = old_ag->jit;
  610. Z_PTR_P(zv) = new_ag;
  611. }
  612. /* }}} */
  613. static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{{ */
  614. {
  615. compiler_globals->compiled_filename = NULL;
  616. compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
  617. zend_hash_init(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
  618. zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
  619. compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
  620. zend_hash_init(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1);
  621. zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
  622. zend_set_default_compile_time_values();
  623. compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
  624. zend_hash_init(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1);
  625. zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
  626. compiler_globals->script_encoding_list = NULL;
  627. compiler_globals->current_linking_class = NULL;
  628. #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
  629. /* Map region is going to be created and resized at run-time. */
  630. compiler_globals->map_ptr_real_base = NULL;
  631. compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
  632. compiler_globals->map_ptr_size = 0;
  633. compiler_globals->map_ptr_last = global_map_ptr_last;
  634. if (compiler_globals->map_ptr_last) {
  635. /* Allocate map_ptr table */
  636. compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096);
  637. void *base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
  638. compiler_globals->map_ptr_real_base = base;
  639. compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(base);
  640. memset(base, 0, compiler_globals->map_ptr_last * sizeof(void*));
  641. }
  642. #else
  643. # error "Unknown ZEND_MAP_PTR_KIND"
  644. #endif
  645. }
  646. /* }}} */
  647. static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{{ */
  648. {
  649. if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
  650. zend_hash_destroy(compiler_globals->function_table);
  651. free(compiler_globals->function_table);
  652. }
  653. if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
  654. /* Child classes may reuse structures from parent classes, so destroy in reverse order. */
  655. zend_hash_graceful_reverse_destroy(compiler_globals->class_table);
  656. free(compiler_globals->class_table);
  657. }
  658. if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
  659. zend_hash_destroy(compiler_globals->auto_globals);
  660. free(compiler_globals->auto_globals);
  661. }
  662. if (compiler_globals->script_encoding_list) {
  663. pefree((char*)compiler_globals->script_encoding_list, 1);
  664. }
  665. if (compiler_globals->map_ptr_real_base) {
  666. free(compiler_globals->map_ptr_real_base);
  667. compiler_globals->map_ptr_real_base = NULL;
  668. compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
  669. compiler_globals->map_ptr_size = 0;
  670. }
  671. }
  672. /* }}} */
  673. static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
  674. {
  675. zend_startup_constants();
  676. zend_copy_constants(executor_globals->zend_constants, GLOBAL_CONSTANTS_TABLE);
  677. zend_init_rsrc_plist();
  678. zend_init_exception_op();
  679. zend_init_call_trampoline_op();
  680. memset(&executor_globals->trampoline, 0, sizeof(zend_op_array));
  681. executor_globals->capture_warnings_during_sccp = 0;
  682. ZVAL_UNDEF(&executor_globals->user_error_handler);
  683. ZVAL_UNDEF(&executor_globals->user_exception_handler);
  684. executor_globals->in_autoload = NULL;
  685. executor_globals->current_execute_data = NULL;
  686. executor_globals->current_module = NULL;
  687. executor_globals->exit_status = 0;
  688. #if XPFPA_HAVE_CW
  689. executor_globals->saved_fpu_cw = 0;
  690. #endif
  691. executor_globals->saved_fpu_cw_ptr = NULL;
  692. executor_globals->active = 0;
  693. executor_globals->bailout = NULL;
  694. executor_globals->error_handling = EH_NORMAL;
  695. executor_globals->exception_class = NULL;
  696. executor_globals->exception = NULL;
  697. executor_globals->objects_store.object_buckets = NULL;
  698. executor_globals->current_fiber_context = NULL;
  699. executor_globals->main_fiber_context = NULL;
  700. executor_globals->active_fiber = NULL;
  701. #ifdef ZEND_WIN32
  702. zend_get_windows_version_info(&executor_globals->windows_version_info);
  703. #endif
  704. executor_globals->flags = EG_FLAGS_INITIAL;
  705. executor_globals->record_errors = false;
  706. executor_globals->num_errors = 0;
  707. executor_globals->errors = NULL;
  708. }
  709. /* }}} */
  710. static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
  711. {
  712. zend_ini_dtor(executor_globals->ini_directives);
  713. if (&executor_globals->persistent_list != global_persistent_list) {
  714. zend_destroy_rsrc_list(&executor_globals->persistent_list);
  715. }
  716. if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
  717. zend_hash_destroy(executor_globals->zend_constants);
  718. free(executor_globals->zend_constants);
  719. }
  720. }
  721. /* }}} */
  722. static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
  723. {
  724. zend_copy_ini_directives();
  725. zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
  726. }
  727. /* }}} */
  728. #endif
  729. #if defined(__FreeBSD__) || defined(__DragonFly__)
  730. /* FreeBSD and DragonFly floating point precision fix */
  731. #include <floatingpoint.h>
  732. #endif
  733. static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p) /* {{{ */
  734. {
  735. memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
  736. }
  737. /* }}} */
  738. static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p) /* {{{ */
  739. {
  740. memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
  741. }
  742. /* }}} */
  743. static void module_destructor_zval(zval *zv) /* {{{ */
  744. {
  745. zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
  746. module_destructor(module);
  747. free(module);
  748. }
  749. /* }}} */
  750. static bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
  751. {
  752. /* While we keep registering $GLOBALS as an auto-global, we do not create an
  753. * actual variable for it. Access to it handled specially by the compiler. */
  754. return 0;
  755. }
  756. /* }}} */
  757. void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
  758. {
  759. #ifdef ZTS
  760. zend_compiler_globals *compiler_globals;
  761. zend_executor_globals *executor_globals;
  762. extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
  763. extern ZEND_API ts_rsrc_id language_scanner_globals_id;
  764. #else
  765. extern zend_ini_scanner_globals ini_scanner_globals;
  766. extern zend_php_scanner_globals language_scanner_globals;
  767. #endif
  768. zend_cpu_startup();
  769. #ifdef ZEND_WIN32
  770. php_win32_cp_set_by_id(65001);
  771. #endif
  772. start_memory_manager();
  773. virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
  774. #if defined(__FreeBSD__) || defined(__DragonFly__)
  775. /* FreeBSD and DragonFly floating point precision fix */
  776. fpsetmask(0);
  777. #endif
  778. zend_startup_strtod();
  779. zend_startup_extensions_mechanism();
  780. /* Set up utility functions and values */
  781. zend_error_cb = utility_functions->error_function;
  782. zend_printf = utility_functions->printf_function;
  783. zend_write = utility_functions->write_function;
  784. zend_fopen = utility_functions->fopen_function;
  785. if (!zend_fopen) {
  786. zend_fopen = zend_fopen_wrapper;
  787. }
  788. zend_stream_open_function = utility_functions->stream_open_function;
  789. zend_message_dispatcher_p = utility_functions->message_handler;
  790. zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
  791. zend_ticks_function = utility_functions->ticks_function;
  792. zend_on_timeout = utility_functions->on_timeout;
  793. zend_printf_to_smart_string = utility_functions->printf_to_smart_string_function;
  794. zend_printf_to_smart_str = utility_functions->printf_to_smart_str_function;
  795. zend_getenv = utility_functions->getenv_function;
  796. zend_resolve_path = utility_functions->resolve_path_function;
  797. zend_interrupt_function = NULL;
  798. #ifdef HAVE_DTRACE
  799. /* build with dtrace support */
  800. {
  801. char *tmp = getenv("USE_ZEND_DTRACE");
  802. if (tmp && ZEND_ATOL(tmp)) {
  803. zend_dtrace_enabled = 1;
  804. zend_compile_file = dtrace_compile_file;
  805. zend_execute_ex = dtrace_execute_ex;
  806. zend_execute_internal = dtrace_execute_internal;
  807. zend_observer_error_register(dtrace_error_notify_cb);
  808. } else {
  809. zend_compile_file = compile_file;
  810. zend_execute_ex = execute_ex;
  811. zend_execute_internal = NULL;
  812. }
  813. }
  814. #else
  815. zend_compile_file = compile_file;
  816. zend_execute_ex = execute_ex;
  817. zend_execute_internal = NULL;
  818. #endif /* HAVE_DTRACE */
  819. zend_compile_string = compile_string;
  820. zend_throw_exception_hook = NULL;
  821. /* Set up the default garbage collection implementation. */
  822. gc_collect_cycles = zend_gc_collect_cycles;
  823. zend_vm_init();
  824. /* set up version */
  825. zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
  826. zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
  827. GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
  828. GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
  829. GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
  830. GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
  831. zend_hash_init(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1);
  832. zend_hash_init(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1);
  833. zend_hash_init(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1);
  834. zend_hash_init(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1);
  835. zend_hash_init(&module_registry, 32, NULL, module_destructor_zval, 1);
  836. zend_init_rsrc_list_dtors();
  837. #ifdef ZTS
  838. ts_allocate_fast_id(&compiler_globals_id, &compiler_globals_offset, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
  839. ts_allocate_fast_id(&executor_globals_id, &executor_globals_offset, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
  840. ts_allocate_fast_id(&language_scanner_globals_id, &language_scanner_globals_offset, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
  841. ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
  842. compiler_globals = ts_resource(compiler_globals_id);
  843. executor_globals = ts_resource(executor_globals_id);
  844. compiler_globals_dtor(compiler_globals);
  845. compiler_globals->in_compilation = 0;
  846. compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
  847. compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
  848. *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
  849. *compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
  850. compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
  851. zend_hash_destroy(executor_globals->zend_constants);
  852. *executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
  853. #else
  854. ini_scanner_globals_ctor(&ini_scanner_globals);
  855. php_scanner_globals_ctor(&language_scanner_globals);
  856. zend_set_default_compile_time_values();
  857. #ifdef ZEND_WIN32
  858. zend_get_windows_version_info(&EG(windows_version_info));
  859. #endif
  860. # if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
  861. /* Create a map region, used for indirect pointers from shared to
  862. * process memory. It's allocated once and never resized.
  863. * All processes must map it into the same address space.
  864. */
  865. CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ???
  866. CG(map_ptr_last) = 0;
  867. CG(map_ptr_real_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1);
  868. CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
  869. # elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
  870. /* Map region is going to be created and resized at run-time. */
  871. CG(map_ptr_real_base) = NULL;
  872. CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL);
  873. CG(map_ptr_size) = 0;
  874. CG(map_ptr_last) = 0;
  875. # else
  876. # error "Unknown ZEND_MAP_PTR_KIND"
  877. # endif
  878. #endif
  879. EG(error_reporting) = E_ALL & ~E_NOTICE;
  880. zend_interned_strings_init();
  881. zend_startup_builtin_functions();
  882. zend_register_standard_constants();
  883. zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
  884. #ifndef ZTS
  885. zend_init_rsrc_plist();
  886. zend_init_exception_op();
  887. zend_init_call_trampoline_op();
  888. #endif
  889. zend_ini_startup();
  890. #ifdef ZEND_WIN32
  891. /* Uses INI settings, so needs to be run after it. */
  892. php_win32_cp_setup();
  893. #endif
  894. zend_optimizer_startup();
  895. #ifdef ZTS
  896. tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
  897. tsrm_set_shutdown_handler(zend_interned_strings_dtor);
  898. #endif
  899. }
  900. /* }}} */
  901. void zend_register_standard_ini_entries(void) /* {{{ */
  902. {
  903. zend_register_ini_entries_ex(ini_entries, 0, MODULE_PERSISTENT);
  904. }
  905. /* }}} */
  906. /* Unlink the global (r/o) copies of the class, function and constant tables,
  907. * and use a fresh r/w copy for the startup thread
  908. */
  909. zend_result zend_post_startup(void) /* {{{ */
  910. {
  911. #ifdef ZTS
  912. zend_encoding **script_encoding_list;
  913. zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
  914. zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
  915. #endif
  916. startup_done = true;
  917. if (zend_post_startup_cb) {
  918. zend_result (*cb)(void) = zend_post_startup_cb;
  919. zend_post_startup_cb = NULL;
  920. if (cb() != SUCCESS) {
  921. return FAILURE;
  922. }
  923. }
  924. #ifdef ZTS
  925. *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
  926. *GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
  927. *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
  928. global_map_ptr_last = compiler_globals->map_ptr_last;
  929. short_tags_default = CG(short_tags);
  930. compiler_options_default = CG(compiler_options);
  931. zend_destroy_rsrc_list(&EG(persistent_list));
  932. free(compiler_globals->function_table);
  933. compiler_globals->function_table = NULL;
  934. free(compiler_globals->class_table);
  935. compiler_globals->class_table = NULL;
  936. if (compiler_globals->map_ptr_real_base) {
  937. free(compiler_globals->map_ptr_real_base);
  938. }
  939. compiler_globals->map_ptr_real_base = NULL;
  940. compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
  941. if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
  942. compiler_globals_ctor(compiler_globals);
  943. compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
  944. } else {
  945. compiler_globals_ctor(compiler_globals);
  946. }
  947. free(EG(zend_constants));
  948. EG(zend_constants) = NULL;
  949. executor_globals_ctor(executor_globals);
  950. global_persistent_list = &EG(persistent_list);
  951. zend_copy_ini_directives();
  952. #else
  953. global_map_ptr_last = CG(map_ptr_last);
  954. #endif
  955. return SUCCESS;
  956. }
  957. /* }}} */
  958. void zend_shutdown(void) /* {{{ */
  959. {
  960. zend_vm_dtor();
  961. zend_destroy_rsrc_list(&EG(persistent_list));
  962. zend_destroy_modules();
  963. virtual_cwd_deactivate();
  964. virtual_cwd_shutdown();
  965. zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
  966. /* Child classes may reuse structures from parent classes, so destroy in reverse order. */
  967. zend_hash_graceful_reverse_destroy(GLOBAL_CLASS_TABLE);
  968. zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
  969. free(GLOBAL_AUTO_GLOBALS_TABLE);
  970. zend_shutdown_extensions();
  971. free(zend_version_info);
  972. free(GLOBAL_FUNCTION_TABLE);
  973. free(GLOBAL_CLASS_TABLE);
  974. zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
  975. free(GLOBAL_CONSTANTS_TABLE);
  976. zend_shutdown_strtod();
  977. zend_attributes_shutdown();
  978. #ifdef ZTS
  979. GLOBAL_FUNCTION_TABLE = NULL;
  980. GLOBAL_CLASS_TABLE = NULL;
  981. GLOBAL_AUTO_GLOBALS_TABLE = NULL;
  982. GLOBAL_CONSTANTS_TABLE = NULL;
  983. ts_free_id(executor_globals_id);
  984. ts_free_id(compiler_globals_id);
  985. #else
  986. if (CG(map_ptr_real_base)) {
  987. free(CG(map_ptr_real_base));
  988. CG(map_ptr_real_base) = NULL;
  989. CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL);
  990. CG(map_ptr_size) = 0;
  991. }
  992. if (CG(script_encoding_list)) {
  993. free(ZEND_VOIDP(CG(script_encoding_list)));
  994. CG(script_encoding_list) = NULL;
  995. CG(script_encoding_list_size) = 0;
  996. }
  997. #endif
  998. zend_destroy_rsrc_list_dtors();
  999. zend_optimizer_shutdown();
  1000. startup_done = false;
  1001. }
  1002. /* }}} */
  1003. void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
  1004. {
  1005. zend_uv = *utility_values;
  1006. }
  1007. /* }}} */
  1008. /* this should be compatible with the standard zenderror */
  1009. ZEND_COLD void zenderror(const char *error) /* {{{ */
  1010. {
  1011. CG(parse_error) = 0;
  1012. if (EG(exception)) {
  1013. /* An exception was thrown in the lexer, don't throw another in the parser. */
  1014. return;
  1015. }
  1016. zend_throw_exception(zend_ce_parse_error, error, 0);
  1017. }
  1018. /* }}} */
  1019. ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */
  1020. {
  1021. if (!EG(bailout)) {
  1022. zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
  1023. exit(-1);
  1024. }
  1025. gc_protect(1);
  1026. CG(unclean_shutdown) = 1;
  1027. CG(active_class_entry) = NULL;
  1028. CG(in_compilation) = 0;
  1029. EG(current_execute_data) = NULL;
  1030. LONGJMP(*EG(bailout), FAILURE);
  1031. }
  1032. /* }}} */
  1033. ZEND_API size_t zend_get_page_size(void)
  1034. {
  1035. #ifdef _WIN32
  1036. SYSTEM_INFO system_info;
  1037. GetSystemInfo(&system_info);
  1038. return system_info.dwPageSize;
  1039. #elif defined(__FreeBSD__)
  1040. /* This returns the value obtained from
  1041. * the auxv vector, avoiding a syscall. */
  1042. return getpagesize();
  1043. #else
  1044. return (size_t) sysconf(_SC_PAGESIZE);
  1045. #endif
  1046. }
  1047. ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
  1048. {
  1049. char *new_info;
  1050. uint32_t new_info_length;
  1051. new_info_length = (uint32_t)(sizeof(" with v, , by \n")
  1052. + strlen(extension->name)
  1053. + strlen(extension->version)
  1054. + strlen(extension->copyright)
  1055. + strlen(extension->author));
  1056. new_info = (char *) malloc(new_info_length + 1);
  1057. snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
  1058. zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
  1059. strncat(zend_version_info, new_info, new_info_length);
  1060. zend_version_info_length += new_info_length;
  1061. free(new_info);
  1062. }
  1063. /* }}} */
  1064. ZEND_API const char *get_zend_version(void) /* {{{ */
  1065. {
  1066. return zend_version_info;
  1067. }
  1068. /* }}} */
  1069. ZEND_API void zend_activate(void) /* {{{ */
  1070. {
  1071. #ifdef ZTS
  1072. virtual_cwd_activate();
  1073. #endif
  1074. gc_reset();
  1075. init_compiler();
  1076. init_executor();
  1077. startup_scanner();
  1078. if (CG(map_ptr_last)) {
  1079. memset(CG(map_ptr_real_base), 0, CG(map_ptr_last) * sizeof(void*));
  1080. }
  1081. zend_observer_activate();
  1082. }
  1083. /* }}} */
  1084. void zend_call_destructors(void) /* {{{ */
  1085. {
  1086. zend_try {
  1087. shutdown_destructors();
  1088. } zend_end_try();
  1089. }
  1090. /* }}} */
  1091. ZEND_API void zend_deactivate(void) /* {{{ */
  1092. {
  1093. /* we're no longer executing anything */
  1094. EG(current_execute_data) = NULL;
  1095. zend_try {
  1096. shutdown_scanner();
  1097. } zend_end_try();
  1098. /* shutdown_executor() takes care of its own bailout handling */
  1099. shutdown_executor();
  1100. zend_try {
  1101. zend_ini_deactivate();
  1102. } zend_end_try();
  1103. zend_try {
  1104. shutdown_compiler();
  1105. } zend_end_try();
  1106. zend_destroy_rsrc_list(&EG(regular_list));
  1107. #if GC_BENCH
  1108. fprintf(stderr, "GC Statistics\n");
  1109. fprintf(stderr, "-------------\n");
  1110. fprintf(stderr, "Runs: %d\n", GC_G(gc_runs));
  1111. fprintf(stderr, "Collected: %d\n", GC_G(collected));
  1112. fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
  1113. fprintf(stderr, "Root buffer peak: %d\n\n", GC_G(root_buf_peak));
  1114. fprintf(stderr, " Possible Remove from Marked\n");
  1115. fprintf(stderr, " Root Buffered buffer grey\n");
  1116. fprintf(stderr, " -------- -------- ----------- ------\n");
  1117. fprintf(stderr, "ZVAL %8d %8d %9d %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
  1118. #endif
  1119. }
  1120. /* }}} */
  1121. ZEND_API void zend_message_dispatcher(zend_long message, const void *data) /* {{{ */
  1122. {
  1123. if (zend_message_dispatcher_p) {
  1124. zend_message_dispatcher_p(message, data);
  1125. }
  1126. }
  1127. /* }}} */
  1128. ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
  1129. {
  1130. if (zend_get_configuration_directive_p) {
  1131. return zend_get_configuration_directive_p(name);
  1132. } else {
  1133. return NULL;
  1134. }
  1135. }
  1136. /* }}} */
  1137. #define SAVE_STACK(stack) do { \
  1138. if (CG(stack).top) { \
  1139. memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
  1140. CG(stack).top = CG(stack).max = 0; \
  1141. CG(stack).elements = NULL; \
  1142. } else { \
  1143. stack.top = 0; \
  1144. } \
  1145. } while (0)
  1146. #define RESTORE_STACK(stack) do { \
  1147. if (stack.top) { \
  1148. zend_stack_destroy(&CG(stack)); \
  1149. memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
  1150. } \
  1151. } while (0)
  1152. ZEND_API ZEND_COLD void zend_error_zstr_at(
  1153. int orig_type, zend_string *error_filename, uint32_t error_lineno, zend_string *message)
  1154. {
  1155. zval params[4];
  1156. zval retval;
  1157. zval orig_user_error_handler;
  1158. bool in_compilation;
  1159. zend_class_entry *saved_class_entry;
  1160. zend_stack loop_var_stack;
  1161. zend_stack delayed_oplines_stack;
  1162. int type = orig_type & E_ALL;
  1163. bool orig_record_errors;
  1164. uint32_t orig_num_errors;
  1165. zend_error_info **orig_errors;
  1166. zend_result res;
  1167. /* If we're executing a function during SCCP, count any warnings that may be emitted,
  1168. * but don't perform any other error handling. */
  1169. if (EG(capture_warnings_during_sccp)) {
  1170. ZEND_ASSERT(!(type & E_FATAL_ERRORS) && "Fatal error during SCCP");
  1171. EG(capture_warnings_during_sccp)++;
  1172. return;
  1173. }
  1174. if (EG(record_errors)) {
  1175. zend_error_info *info = emalloc(sizeof(zend_error_info));
  1176. info->type = type;
  1177. info->lineno = error_lineno;
  1178. info->filename = zend_string_copy(error_filename);
  1179. info->message = zend_string_copy(message);
  1180. /* This is very inefficient for a large number of errors.
  1181. * Use pow2 realloc if it becomes a problem. */
  1182. EG(num_errors)++;
  1183. EG(errors) = erealloc(EG(errors), sizeof(zend_error_info) * EG(num_errors));
  1184. EG(errors)[EG(num_errors)-1] = info;
  1185. }
  1186. /* Report about uncaught exception in case of fatal errors */
  1187. if (EG(exception)) {
  1188. zend_execute_data *ex;
  1189. const zend_op *opline;
  1190. if (type & E_FATAL_ERRORS) {
  1191. ex = EG(current_execute_data);
  1192. opline = NULL;
  1193. while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
  1194. ex = ex->prev_execute_data;
  1195. }
  1196. if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
  1197. EG(opline_before_exception)) {
  1198. opline = EG(opline_before_exception);
  1199. }
  1200. zend_exception_error(EG(exception), E_WARNING);
  1201. EG(exception) = NULL;
  1202. if (opline) {
  1203. ex->opline = opline;
  1204. }
  1205. }
  1206. }
  1207. zend_observer_error_notify(type, error_filename, error_lineno, message);
  1208. /* if we don't have a user defined error handler */
  1209. if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
  1210. || !(EG(user_error_handler_error_reporting) & type)
  1211. || EG(error_handling) != EH_NORMAL) {
  1212. zend_error_cb(orig_type, error_filename, error_lineno, message);
  1213. } else switch (type) {
  1214. case E_ERROR:
  1215. case E_PARSE:
  1216. case E_CORE_ERROR:
  1217. case E_CORE_WARNING:
  1218. case E_COMPILE_ERROR:
  1219. case E_COMPILE_WARNING:
  1220. /* The error may not be safe to handle in user-space */
  1221. zend_error_cb(orig_type, error_filename, error_lineno, message);
  1222. break;
  1223. default:
  1224. /* Handle the error in user space */
  1225. ZVAL_STR_COPY(&params[1], message);
  1226. ZVAL_LONG(&params[0], type);
  1227. if (error_filename) {
  1228. ZVAL_STR_COPY(&params[2], error_filename);
  1229. } else {
  1230. ZVAL_NULL(&params[2]);
  1231. }
  1232. ZVAL_LONG(&params[3], error_lineno);
  1233. ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
  1234. ZVAL_UNDEF(&EG(user_error_handler));
  1235. /* User error handler may include() additional PHP files.
  1236. * If an error was generated during compilation PHP will compile
  1237. * such scripts recursively, but some CG() variables may be
  1238. * inconsistent. */
  1239. in_compilation = CG(in_compilation);
  1240. if (in_compilation) {
  1241. saved_class_entry = CG(active_class_entry);
  1242. CG(active_class_entry) = NULL;
  1243. SAVE_STACK(loop_var_stack);
  1244. SAVE_STACK(delayed_oplines_stack);
  1245. CG(in_compilation) = 0;
  1246. }
  1247. orig_record_errors = EG(record_errors);
  1248. orig_num_errors = EG(num_errors);
  1249. orig_errors = EG(errors);
  1250. EG(record_errors) = false;
  1251. EG(num_errors) = 0;
  1252. EG(errors) = NULL;
  1253. res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params);
  1254. EG(record_errors) = orig_record_errors;
  1255. EG(num_errors) = orig_num_errors;
  1256. EG(errors) = orig_errors;
  1257. if (res == SUCCESS) {
  1258. if (Z_TYPE(retval) != IS_UNDEF) {
  1259. if (Z_TYPE(retval) == IS_FALSE) {
  1260. zend_error_cb(orig_type, error_filename, error_lineno, message);
  1261. }
  1262. zval_ptr_dtor(&retval);
  1263. }
  1264. } else if (!EG(exception)) {
  1265. /* The user error handler failed, use built-in error handler */
  1266. zend_error_cb(orig_type, error_filename, error_lineno, message);
  1267. }
  1268. if (in_compilation) {
  1269. CG(active_class_entry) = saved_class_entry;
  1270. RESTORE_STACK(loop_var_stack);
  1271. RESTORE_STACK(delayed_oplines_stack);
  1272. CG(in_compilation) = 1;
  1273. }
  1274. zval_ptr_dtor(&params[2]);
  1275. zval_ptr_dtor(&params[1]);
  1276. if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
  1277. ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
  1278. } else {
  1279. zval_ptr_dtor(&orig_user_error_handler);
  1280. }
  1281. break;
  1282. }
  1283. if (type == E_PARSE) {
  1284. /* eval() errors do not affect exit_status */
  1285. if (!(EG(current_execute_data) &&
  1286. EG(current_execute_data)->func &&
  1287. ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
  1288. EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
  1289. EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
  1290. EG(exit_status) = 255;
  1291. }
  1292. }
  1293. }
  1294. /* }}} */
  1295. static ZEND_COLD void zend_error_va_list(
  1296. int orig_type, zend_string *error_filename, uint32_t error_lineno,
  1297. const char *format, va_list args)
  1298. {
  1299. zend_string *message = zend_vstrpprintf(0, format, args);
  1300. zend_error_zstr_at(orig_type, error_filename, error_lineno, message);
  1301. zend_string_release(message);
  1302. }
  1303. static ZEND_COLD void get_filename_lineno(int type, zend_string **filename, uint32_t *lineno) {
  1304. /* Obtain relevant filename and lineno */
  1305. switch (type) {
  1306. case E_CORE_ERROR:
  1307. case E_CORE_WARNING:
  1308. *filename = NULL;
  1309. *lineno = 0;
  1310. break;
  1311. case E_PARSE:
  1312. case E_COMPILE_ERROR:
  1313. case E_COMPILE_WARNING:
  1314. case E_ERROR:
  1315. case E_NOTICE:
  1316. case E_STRICT:
  1317. case E_DEPRECATED:
  1318. case E_WARNING:
  1319. case E_USER_ERROR:
  1320. case E_USER_WARNING:
  1321. case E_USER_NOTICE:
  1322. case E_USER_DEPRECATED:
  1323. case E_RECOVERABLE_ERROR:
  1324. if (zend_is_compiling()) {
  1325. *filename = zend_get_compiled_filename();
  1326. *lineno = zend_get_compiled_lineno();
  1327. } else if (zend_is_executing()) {
  1328. *filename = zend_get_executed_filename_ex();
  1329. *lineno = zend_get_executed_lineno();
  1330. } else {
  1331. *filename = NULL;
  1332. *lineno = 0;
  1333. }
  1334. break;
  1335. default:
  1336. *filename = NULL;
  1337. *lineno = 0;
  1338. break;
  1339. }
  1340. if (!*filename) {
  1341. *filename = ZSTR_KNOWN(ZEND_STR_UNKNOWN_CAPITALIZED);
  1342. }
  1343. }
  1344. ZEND_API ZEND_COLD void zend_error_at(
  1345. int type, zend_string *filename, uint32_t lineno, const char *format, ...) {
  1346. va_list args;
  1347. if (!filename) {
  1348. uint32_t dummy_lineno;
  1349. get_filename_lineno(type, &filename, &dummy_lineno);
  1350. }
  1351. va_start(args, format);
  1352. zend_error_va_list(type, filename, lineno, format, args);
  1353. va_end(args);
  1354. }
  1355. ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) {
  1356. zend_string *filename;
  1357. uint32_t lineno;
  1358. va_list args;
  1359. get_filename_lineno(type, &filename, &lineno);
  1360. va_start(args, format);
  1361. zend_error_va_list(type, filename, lineno, format, args);
  1362. va_end(args);
  1363. }
  1364. ZEND_API ZEND_COLD void zend_error_unchecked(int type, const char *format, ...) {
  1365. zend_string *filename;
  1366. uint32_t lineno;
  1367. va_list args;
  1368. get_filename_lineno(type, &filename, &lineno);
  1369. va_start(args, format);
  1370. zend_error_va_list(type, filename, lineno, format, args);
  1371. va_end(args);
  1372. }
  1373. ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(
  1374. int type, zend_string *filename, uint32_t lineno, const char *format, ...)
  1375. {
  1376. va_list args;
  1377. if (!filename) {
  1378. uint32_t dummy_lineno;
  1379. get_filename_lineno(type, &filename, &dummy_lineno);
  1380. }
  1381. va_start(args, format);
  1382. zend_error_va_list(type, filename, lineno, format, args);
  1383. va_end(args);
  1384. /* Should never reach this. */
  1385. abort();
  1386. }
  1387. ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
  1388. {
  1389. zend_string *filename;
  1390. uint32_t lineno;
  1391. va_list args;
  1392. get_filename_lineno(type, &filename, &lineno);
  1393. va_start(args, format);
  1394. zend_error_va_list(type, filename, lineno, format, args);
  1395. va_end(args);
  1396. /* Should never reach this. */
  1397. abort();
  1398. }
  1399. ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
  1400. zend_string *filename;
  1401. uint32_t lineno;
  1402. get_filename_lineno(type, &filename, &lineno);
  1403. zend_error_zstr_at(type, filename, lineno, message);
  1404. }
  1405. ZEND_API void zend_begin_record_errors(void)
  1406. {
  1407. ZEND_ASSERT(!EG(record_errors) && "Error recording already enabled");
  1408. EG(record_errors) = true;
  1409. EG(num_errors) = 0;
  1410. EG(errors) = NULL;
  1411. }
  1412. ZEND_API void zend_emit_recorded_errors(void)
  1413. {
  1414. EG(record_errors) = false;
  1415. for (uint32_t i = 0; i < EG(num_errors); i++) {
  1416. zend_error_info *error = EG(errors)[i];
  1417. zend_error_zstr_at(error->type, error->filename, error->lineno, error->message);
  1418. }
  1419. }
  1420. ZEND_API void zend_free_recorded_errors(void)
  1421. {
  1422. if (!EG(num_errors)) {
  1423. return;
  1424. }
  1425. for (uint32_t i = 0; i < EG(num_errors); i++) {
  1426. zend_error_info *info = EG(errors)[i];
  1427. zend_string_release(info->filename);
  1428. zend_string_release(info->message);
  1429. efree(info);
  1430. }
  1431. efree(EG(errors));
  1432. EG(errors) = NULL;
  1433. EG(num_errors) = 0;
  1434. }
  1435. ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
  1436. {
  1437. va_list va;
  1438. char *message = NULL;
  1439. if (!exception_ce) {
  1440. exception_ce = zend_ce_error;
  1441. }
  1442. /* Marker used to disable exception generation during preloading. */
  1443. if (EG(exception) == (void*)(uintptr_t)-1) {
  1444. return;
  1445. }
  1446. va_start(va, format);
  1447. zend_vspprintf(&message, 0, format, va);
  1448. //TODO: we can't convert compile-time errors to exceptions yet???
  1449. if (EG(current_execute_data) && !CG(in_compilation)) {
  1450. zend_throw_exception(exception_ce, message, 0);
  1451. } else {
  1452. zend_error(E_ERROR, "%s", message);
  1453. }
  1454. efree(message);
  1455. va_end(va);
  1456. }
  1457. /* }}} */
  1458. ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
  1459. {
  1460. va_list va;
  1461. char *message = NULL;
  1462. va_start(va, format);
  1463. zend_vspprintf(&message, 0, format, va);
  1464. zend_throw_exception(zend_ce_type_error, message, 0);
  1465. efree(message);
  1466. va_end(va);
  1467. } /* }}} */
  1468. ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) /* {{{ */
  1469. {
  1470. va_list va;
  1471. char *message = NULL;
  1472. va_start(va, format);
  1473. zend_vspprintf(&message, 0, format, va);
  1474. zend_throw_exception(zend_ce_argument_count_error, message, 0);
  1475. efree(message);
  1476. va_end(va);
  1477. } /* }}} */
  1478. ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) /* {{{ */
  1479. {
  1480. va_list va;
  1481. char *message = NULL;
  1482. va_start(va, format);
  1483. zend_vspprintf(&message, 0, format, va);
  1484. zend_throw_exception(zend_ce_value_error, message, 0);
  1485. efree(message);
  1486. va_end(va);
  1487. } /* }}} */
  1488. ZEND_API ZEND_COLD void zend_output_debug_string(bool trigger_break, const char *format, ...) /* {{{ */
  1489. {
  1490. #if ZEND_DEBUG
  1491. va_list args;
  1492. va_start(args, format);
  1493. # ifdef ZEND_WIN32
  1494. {
  1495. char output_buf[1024];
  1496. vsnprintf(output_buf, 1024, format, args);
  1497. OutputDebugString(output_buf);
  1498. OutputDebugString("\n");
  1499. if (trigger_break && IsDebuggerPresent()) {
  1500. DebugBreak();
  1501. }
  1502. }
  1503. # else
  1504. vfprintf(stderr, format, args);
  1505. fprintf(stderr, "\n");
  1506. # endif
  1507. va_end(args);
  1508. #endif
  1509. }
  1510. /* }}} */
  1511. ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */
  1512. {
  1513. zval orig_user_exception_handler;
  1514. zval params[1], retval2;
  1515. zend_object *old_exception;
  1516. if (zend_is_unwind_exit(EG(exception))) {
  1517. return;
  1518. }
  1519. old_exception = EG(exception);
  1520. EG(exception) = NULL;
  1521. ZVAL_OBJ(&params[0], old_exception);
  1522. ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
  1523. if (call_user_function(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params) == SUCCESS) {
  1524. zval_ptr_dtor(&retval2);
  1525. if (EG(exception)) {
  1526. OBJ_RELEASE(EG(exception));
  1527. EG(exception) = NULL;
  1528. }
  1529. OBJ_RELEASE(old_exception);
  1530. } else {
  1531. EG(exception) = old_exception;
  1532. }
  1533. } /* }}} */
  1534. ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
  1535. {
  1536. va_list files;
  1537. int i;
  1538. zend_file_handle *file_handle;
  1539. zend_op_array *op_array;
  1540. zend_result ret = SUCCESS;
  1541. va_start(files, file_count);
  1542. for (i = 0; i < file_count; i++) {
  1543. file_handle = va_arg(files, zend_file_handle *);
  1544. if (!file_handle) {
  1545. continue;
  1546. }
  1547. if (ret == FAILURE) {
  1548. continue;
  1549. }
  1550. op_array = zend_compile_file(file_handle, type);
  1551. if (file_handle->opened_path) {
  1552. zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
  1553. }
  1554. if (op_array) {
  1555. zend_execute(op_array, retval);
  1556. zend_exception_restore();
  1557. if (UNEXPECTED(EG(exception))) {
  1558. if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
  1559. zend_user_exception_handler();
  1560. }
  1561. if (EG(exception)) {
  1562. ret = zend_exception_error(EG(exception), E_ERROR);
  1563. }
  1564. }
  1565. zend_destroy_static_vars(op_array);
  1566. destroy_op_array(op_array);
  1567. efree_size(op_array, sizeof(zend_op_array));
  1568. } else if (type==ZEND_REQUIRE) {
  1569. ret = FAILURE;
  1570. }
  1571. }
  1572. va_end(files);
  1573. return ret;
  1574. }
  1575. /* }}} */
  1576. #define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
  1577. ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
  1578. {
  1579. const char *cur_filename;
  1580. int cur_lineno;
  1581. char *compiled_string_description;
  1582. if (zend_is_compiling()) {
  1583. cur_filename = ZSTR_VAL(zend_get_compiled_filename());
  1584. cur_lineno = zend_get_compiled_lineno();
  1585. } else if (zend_is_executing()) {
  1586. cur_filename = zend_get_executed_filename();
  1587. cur_lineno = zend_get_executed_lineno();
  1588. } else {
  1589. cur_filename = "Unknown";
  1590. cur_lineno = 0;
  1591. }
  1592. zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
  1593. return compiled_string_description;
  1594. }
  1595. /* }}} */
  1596. void free_estring(char **str_p) /* {{{ */
  1597. {
  1598. efree(*str_p);
  1599. }
  1600. /* }}} */
  1601. ZEND_API void zend_map_ptr_reset(void)
  1602. {
  1603. CG(map_ptr_last) = global_map_ptr_last;
  1604. }
  1605. ZEND_API void *zend_map_ptr_new(void)
  1606. {
  1607. void **ptr;
  1608. if (CG(map_ptr_last) >= CG(map_ptr_size)) {
  1609. #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
  1610. // TODO: error ???
  1611. ZEND_UNREACHABLE();
  1612. #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
  1613. /* Grow map_ptr table */
  1614. CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
  1615. CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), CG(map_ptr_size) * sizeof(void*), 1);
  1616. CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
  1617. #else
  1618. # error "Unknown ZEND_MAP_PTR_KIND"
  1619. #endif
  1620. }
  1621. ptr = (void**)CG(map_ptr_real_base) + CG(map_ptr_last);
  1622. *ptr = NULL;
  1623. CG(map_ptr_last)++;
  1624. #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
  1625. return ptr;
  1626. #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
  1627. return ZEND_MAP_PTR_PTR2OFFSET(ptr);
  1628. #else
  1629. # error "Unknown ZEND_MAP_PTR_KIND"
  1630. #endif
  1631. }
  1632. ZEND_API void zend_map_ptr_extend(size_t last)
  1633. {
  1634. if (last > CG(map_ptr_last)) {
  1635. void **ptr;
  1636. if (last >= CG(map_ptr_size)) {
  1637. #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
  1638. /* This may never happen */
  1639. ZEND_UNREACHABLE();
  1640. #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
  1641. /* Grow map_ptr table */
  1642. CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096);
  1643. CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), CG(map_ptr_size) * sizeof(void*), 1);
  1644. CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
  1645. #else
  1646. # error "Unknown ZEND_MAP_PTR_KIND"
  1647. #endif
  1648. }
  1649. ptr = (void**)CG(map_ptr_real_base) + CG(map_ptr_last);
  1650. memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*));
  1651. CG(map_ptr_last) = last;
  1652. }
  1653. }
  1654. ZEND_API void zend_alloc_ce_cache(zend_string *type_name)
  1655. {
  1656. if (ZSTR_HAS_CE_CACHE(type_name) || !ZSTR_IS_INTERNED(type_name)) {
  1657. return;
  1658. }
  1659. if ((GC_FLAGS(type_name) & IS_STR_PERMANENT) && startup_done) {
  1660. /* Don't allocate slot on permanent interned string outside module startup.
  1661. * The cache slot would no longer be valid on the next request. */
  1662. return;
  1663. }
  1664. if (zend_string_equals_literal_ci(type_name, "self")
  1665. || zend_string_equals_literal_ci(type_name, "parent")) {
  1666. return;
  1667. }
  1668. /* We use the refcount to keep map_ptr of corresponding type */
  1669. uint32_t ret;
  1670. do {
  1671. ret = ZEND_MAP_PTR_NEW_OFFSET();
  1672. } while (ret <= 2);
  1673. GC_ADD_FLAGS(type_name, IS_STR_CLASS_NAME_MAP_PTR);
  1674. GC_SET_REFCOUNT(type_name, ret);
  1675. }