mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-11 11:10:49 +00:00
Compare commits
1087
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1ffeb3a7f | ||
|
|
896b34177e | ||
|
|
81b4ce3ea3 | ||
|
|
21bc7464f4 | ||
|
|
f4f068000b | ||
|
|
569b85d9a2 | ||
|
|
02950dc616 | ||
|
|
0ba32e5cf9 | ||
|
|
8404f8ac2a | ||
|
|
27ff425b78 | ||
|
|
448ef30f75 | ||
|
|
0cc2810498 | ||
|
|
4756207e7e | ||
|
|
339139f876 | ||
|
|
480044a0ea | ||
|
|
eb1a1d5feb | ||
|
|
4bb580adb1 | ||
|
|
1b6d076244 | ||
|
|
38f1b569c2 | ||
|
|
ea1c0c5627 | ||
|
|
e372e037dd | ||
|
|
4a9ad2faff | ||
|
|
3de6f80ff5 | ||
|
|
488d3dac2e | ||
|
|
7d2f8525d8 | ||
|
|
95183cc339 | ||
|
|
184b6d9e73 | ||
|
|
ec550cd783 | ||
|
|
eeae4651f7 | ||
|
|
97f894e189 | ||
|
|
5639c3350e | ||
|
|
75f93ed663 | ||
|
|
03ae6f22b6 | ||
|
|
d104f2ea88 | ||
|
|
4ed261870f | ||
|
|
c772261319 | ||
|
|
ebb98e7aeb | ||
|
|
5c0f03275e | ||
|
|
28e44f9d44 | ||
|
|
d3f171117c | ||
|
|
5fe54dbaf9 | ||
|
|
ede59c8feb | ||
|
|
c06f66563a | ||
|
|
b644dcfb72 | ||
|
|
919abf0cb1 | ||
|
|
83db775323 | ||
|
|
fe46966678 | ||
|
|
244fc1e053 | ||
|
|
ce6cbb3110 | ||
|
|
a0cf63f526 | ||
|
|
99162b8198 | ||
|
|
85b4a65520 | ||
|
|
091ea62262 | ||
|
|
d92a87d7cb | ||
|
|
3ef6e3726c | ||
|
|
211f4ceeae | ||
|
|
ab3a746a2d | ||
|
|
3485925a3a | ||
|
|
d5123415f6 | ||
|
|
6e36ded569 | ||
|
|
4c0f17caca | ||
|
|
71c970077d | ||
|
|
f9ad308669 | ||
|
|
fbf3a6bc1a | ||
|
|
24125f0f26 | ||
|
|
422f323982 | ||
|
|
a72cd07f29 | ||
|
|
83e5547827 | ||
|
|
aa192f57c9 | ||
|
|
76d6c4f9ec | ||
|
|
faba230153 | ||
|
|
316f72ce28 | ||
|
|
80260bcfa6 | ||
|
|
bba4a8aad5 | ||
|
|
87ccf50bad | ||
|
|
aa394e70ff | ||
|
|
f382fbf4c1 | ||
|
|
5fc2fede9c | ||
|
|
ffae8f1549 | ||
|
|
54b3871b11 | ||
|
|
5a67d9a229 | ||
|
|
925fa271ec | ||
|
|
cd387b4575 | ||
|
|
c6a7d1eaed | ||
|
|
8fe4cc6d28 | ||
|
|
681a1afd3f | ||
|
|
8efd73c4d2 | ||
|
|
622a346302 | ||
|
|
53f129a44d | ||
|
|
b75867fff0 | ||
|
|
630f9c33c2 | ||
|
|
181f34f375 | ||
|
|
9c4de388c6 | ||
|
|
505adabf25 | ||
|
|
51771ed238 | ||
|
|
f804a3614e | ||
|
|
034e6decb3 | ||
|
|
2e5de0c323 | ||
|
|
8bd67ce748 | ||
|
|
ba62b9bbf8 | ||
|
|
07b5896a13 | ||
|
|
3769aee67c | ||
|
|
9beb3763db | ||
|
|
238529fc3e | ||
|
|
a0d848f795 | ||
|
|
d43d0663af | ||
|
|
86f1875536 | ||
|
|
4cda98264e | ||
|
|
d5dd29ce5c | ||
|
|
d6eb3b49c8 | ||
|
|
ee226b961c | ||
|
|
d1a2c15221 | ||
|
|
895b4efab0 | ||
|
|
fbe9b2c088 | ||
|
|
b1709b8ff0 | ||
|
|
c96ffaa653 | ||
|
|
3affc0e8a2 | ||
|
|
97df260b27 | ||
|
|
0323f66fa2 | ||
|
|
13f1c276ab | ||
|
|
21da246807 | ||
|
|
c5f7dcd1dc | ||
|
|
a96957f0da | ||
|
|
4a82cdce66 | ||
|
|
20d93534d5 | ||
|
|
e6f9059a86 | ||
|
|
9a1fc445bf | ||
|
|
a67a5dc0ad | ||
|
|
eda813fd37 | ||
|
|
744ada7d9d | ||
|
|
9d4f4483cb | ||
|
|
4078c35939 | ||
|
|
5f9a68d3ef | ||
|
|
278c38165c | ||
|
|
e6ad29ae96 | ||
|
|
dd791cd717 | ||
|
|
41a2f7074d | ||
|
|
0854fd8b81 | ||
|
|
5d126245a3 | ||
|
|
08241ee3f3 | ||
|
|
9016018ccc | ||
|
|
373aa7c81f | ||
|
|
8d79139980 | ||
|
|
ebaf130a15 | ||
|
|
1b4d5ad46a | ||
|
|
b120f9beb2 | ||
|
|
625b929c6e | ||
|
|
381fd62ccf | ||
|
|
79131b4617 | ||
|
|
0e985d3726 | ||
|
|
0e67973e9a | ||
|
|
5104c2bbc3 | ||
|
|
3add3491b3 | ||
|
|
4c0bd5e77a | ||
|
|
a3e4b889e7 | ||
|
|
297f582f5c | ||
|
|
fccd1eda5f | ||
|
|
0e09e5e6fa | ||
|
|
fa863c9ea3 | ||
|
|
7943f944c2 | ||
|
|
cb9cc6b8e1 | ||
|
|
ee709c5366 | ||
|
|
1e40b0aff6 | ||
|
|
557026301f | ||
|
|
6cf5ac7567 | ||
|
|
c65143d571 | ||
|
|
9c5d84ace1 | ||
|
|
4f9f7c7948 | ||
|
|
52b41f24e3 | ||
|
|
2bcf8a6cd9 | ||
|
|
a8b49bbf18 | ||
|
|
b0f7a46b21 | ||
|
|
43c36bdb73 | ||
|
|
5deac25ea0 | ||
|
|
f3b4c05423 | ||
|
|
13aaba40cd | ||
|
|
65fce7f950 | ||
|
|
cd68c4b1d2 | ||
|
|
e346608209 | ||
|
|
d81b7c4450 | ||
|
|
4d743eee5f | ||
|
|
b28c3eb47e | ||
|
|
196b768928 | ||
|
|
6f3714a8fc | ||
|
|
c45fcfd063 | ||
|
|
a0c03a3ec5 | ||
|
|
fe4a5abf30 | ||
|
|
b6d624e54e | ||
|
|
f33bd9c846 | ||
|
|
cb6dea6ea8 | ||
|
|
d964832255 | ||
|
|
a3a0e49586 | ||
|
|
c370683903 | ||
|
|
c1ec815fae | ||
|
|
f4a0e601ee | ||
|
|
bfe7c6988f | ||
|
|
904dca6392 | ||
|
|
d037785165 | ||
|
|
2a73d56ef9 | ||
|
|
85e2e6c1fd | ||
|
|
977d84490b | ||
|
|
7b44790db5 | ||
|
|
a87300241f | ||
|
|
cb1a297bf4 | ||
|
|
e0b6e5222b | ||
|
|
f75da60b18 | ||
|
|
1b4368db77 | ||
|
|
7049d3450e | ||
|
|
85bada10c1 | ||
|
|
720ba67948 | ||
|
|
f7eedbe9a6 | ||
|
|
84be568366 | ||
|
|
3003793480 | ||
|
|
39007e23a4 | ||
|
|
4d162a2d9b | ||
|
|
abf5b9481b | ||
|
|
301b7f990a | ||
|
|
7e870c596d | ||
|
|
2d9d10fbbf | ||
|
|
29f51e1ca9 | ||
|
|
4675b79e65 | ||
|
|
de65eaa8c8 | ||
|
|
17094017f7 | ||
|
|
8c08124c0e | ||
|
|
6048ac32b4 | ||
|
|
5d1cc7d135 | ||
|
|
aae5d4d9db | ||
|
|
ffb62112f8 | ||
|
|
977974f95f | ||
|
|
60d5b2ec24 | ||
|
|
04808aa7e1 | ||
|
|
6eaa4d01d3 | ||
|
|
f6aa6324fb | ||
|
|
e1d4ac426c | ||
|
|
57d7b4fc56 | ||
|
|
736279239e | ||
|
|
40e518b4c3 | ||
|
|
19b5bc8ce2 | ||
|
|
c4f9f1ff4c | ||
|
|
a93fb3524e | ||
|
|
59bd4117ac | ||
|
|
605d32bedd | ||
|
|
4bf299a250 | ||
|
|
1813fe9f38 | ||
|
|
cf2cd8fb20 | ||
|
|
7e4b77c921 | ||
|
|
108bf84967 | ||
|
|
a76f8e297d | ||
|
|
b248a7a95c | ||
|
|
619adc9795 | ||
|
|
7c77ca38b1 | ||
|
|
1552d6ae7b | ||
|
|
b0645abdcc | ||
|
|
088f8b528b | ||
|
|
42af411620 | ||
|
|
3ec8730e89 | ||
|
|
fcf21c4d00 | ||
|
|
5d67e8617b | ||
|
|
543ad4b2d3 | ||
|
|
247774e3fd | ||
|
|
aef51819ce | ||
|
|
0afc04b913 | ||
|
|
3656349990 | ||
|
|
fa2a2a1059 | ||
|
|
fe92a811ed | ||
|
|
1414f2c095 | ||
|
|
68126a76b4 | ||
|
|
4576b4d58a | ||
|
|
2c8aee0bb8 | ||
|
|
e116595e63 | ||
|
|
0ca47ba8d8 | ||
|
|
aba95c2399 | ||
|
|
faa396c67d | ||
|
|
f86aa349eb | ||
|
|
3578e5b250 | ||
|
|
09f2355eec | ||
|
|
ac8b1a9de1 | ||
|
|
1db49d8c5b | ||
|
|
f79bf4900a | ||
|
|
7dbc5e5c69 | ||
|
|
4469049b7b | ||
|
|
90445ba4a4 | ||
|
|
d7f27984d2 | ||
|
|
711a3ab9d1 | ||
|
|
a8dfb33db8 | ||
|
|
1330491994 | ||
|
|
9d7206dcea | ||
|
|
24cd25824e | ||
|
|
2c67c0246e | ||
|
|
fa76fa8e32 | ||
|
|
49a133dd0b | ||
|
|
2917c70252 | ||
|
|
926bd6cc7a | ||
|
|
34c1ba5685 | ||
|
|
5351ecbfca | ||
|
|
de075d172c | ||
|
|
a5aae1b66c | ||
|
|
5a3e236bd5 | ||
|
|
03dcf66f9a | ||
|
|
faee48506d | ||
|
|
05394d6056 | ||
|
|
9ef264504d | ||
|
|
7e4de4f8d6 | ||
|
|
6d148f7ed9 | ||
|
|
fa7615af59 | ||
|
|
c7248e6359 | ||
|
|
7386b74b07 | ||
|
|
8439eb6277 | ||
|
|
437ab7f1f4 | ||
|
|
dd70a2c7ae | ||
|
|
4dc994571d | ||
|
|
5ef138b0c7 | ||
|
|
489bfb0af9 | ||
|
|
c8dd415543 | ||
|
|
6e17a439a9 | ||
|
|
9664312e30 | ||
|
|
c50ee655ea | ||
|
|
6b974874ab | ||
|
|
3a3f67f79b | ||
|
|
fd5c421a00 | ||
|
|
b924af8db9 | ||
|
|
515fa6160d | ||
|
|
bc55af0cf2 | ||
|
|
96cde1841a | ||
|
|
9a06628c80 | ||
|
|
99fa36cc58 | ||
|
|
ab3525c401 | ||
|
|
cd3b46f28a | ||
|
|
64b9277867 | ||
|
|
59a9e7af21 | ||
|
|
1e14f805f9 | ||
|
|
0581e877a5 | ||
|
|
f2e33dc725 | ||
|
|
56fac96bec | ||
|
|
502ce90873 | ||
|
|
b97fd60b42 | ||
|
|
8be510ae63 | ||
|
|
5be75da202 | ||
|
|
c4ca220467 | ||
|
|
d10df70f4e | ||
|
|
1f4972e348 | ||
|
|
9e8d4a1b06 | ||
|
|
8beb153460 | ||
|
|
5234c2941f | ||
|
|
4ab05e8f69 | ||
|
|
61f6cd0da5 | ||
|
|
cf3a902286 | ||
|
|
29d2c13809 | ||
|
|
245d01892a | ||
|
|
73cb5ca777 | ||
|
|
b664909397 | ||
|
|
d467761663 | ||
|
|
620db04e91 | ||
|
|
bd3bc097b0 | ||
|
|
9fb816f45a | ||
|
|
15d8601866 | ||
|
|
6e1e113b91 | ||
|
|
5c6ccb2d8f | ||
|
|
7ef559ff80 | ||
|
|
e25b23d1c9 | ||
|
|
6c3768b154 | ||
|
|
65ca28b463 | ||
|
|
2ec7f04f7e | ||
|
|
a52ff5cde6 | ||
|
|
36a2e235dd | ||
|
|
96249b68e5 | ||
|
|
278d71e508 | ||
|
|
9cfe459e21 | ||
|
|
54af278762 | ||
|
|
b61dba5e1d | ||
|
|
8ca69ff641 | ||
|
|
f97fc096a3 | ||
|
|
9fd54bd9d8 | ||
|
|
914787491d | ||
|
|
1939097ede | ||
|
|
a128cbad57 | ||
|
|
49be4af42b | ||
|
|
befce20c84 | ||
|
|
909d44f20d | ||
|
|
7e0ccb6d12 | ||
|
|
48c0cf7df6 | ||
|
|
1e92b24a2a | ||
|
|
a521d7e1be | ||
|
|
c5a1c5f5a4 | ||
|
|
4a36482378 | ||
|
|
d438bcf226 | ||
|
|
858c9d86fa | ||
|
|
c40e665ecd | ||
|
|
f164df0b7b | ||
|
|
9a43410871 | ||
|
|
5674827ead | ||
|
|
03cf70ab1e | ||
|
|
ec26d7a80f | ||
|
|
51394dff3f | ||
|
|
8c0cc49b9b | ||
|
|
a740f9e783 | ||
|
|
d8868b654e | ||
|
|
c996a9899e | ||
|
|
d9fd670fdc | ||
|
|
09f9f7ce50 | ||
|
|
873a460c7c | ||
|
|
1504e9c9df | ||
|
|
82c71158c1 | ||
|
|
45b17d0f96 | ||
|
|
6d9b4ca5fc | ||
|
|
3a8103ae47 | ||
|
|
f22e0c0a6a | ||
|
|
4475cbdc85 | ||
|
|
4657289e87 | ||
|
|
10a957ed35 | ||
|
|
23fd22f9ed | ||
|
|
51acb9dddd | ||
|
|
e52295988c | ||
|
|
69b9381901 | ||
|
|
9871cf78f6 | ||
|
|
1d9bb287c5 | ||
|
|
548352aa1e | ||
|
|
546fb3407d | ||
|
|
e4974f6cc6 | ||
|
|
b7bc907cfd | ||
|
|
5112fdd670 | ||
|
|
d66640a334 | ||
|
|
23db119768 | ||
|
|
063a06b8e5 | ||
|
|
1b15620744 | ||
|
|
86127a077f | ||
|
|
faaea4f304 | ||
|
|
00e763f499 | ||
|
|
fea84a1c9c | ||
|
|
5f15d6f0d8 | ||
|
|
07655ffe7e | ||
|
|
65fee90462 | ||
|
|
14d3e173aa | ||
|
|
9e072d9565 | ||
|
|
1b143f4033 | ||
|
|
4571cc2195 | ||
|
|
99b538a722 | ||
|
|
98b22864ff | ||
|
|
2323e95df9 | ||
|
|
74d6c23b39 | ||
|
|
a2e7b9162c | ||
|
|
654bb8faf3 | ||
|
|
791fc70025 | ||
|
|
b05e123cde | ||
|
|
db5ad4c51f | ||
|
|
a19d96fc58 | ||
|
|
695a102ede | ||
|
|
399ec40a76 | ||
|
|
e003c56c74 | ||
|
|
327d4f9afb | ||
|
|
96c5c1ef59 | ||
|
|
ad468d20b1 | ||
|
|
bff7dc70d8 | ||
|
|
19992250cf | ||
|
|
3e4b91ec7f | ||
|
|
7d69fa7179 | ||
|
|
eacf998af2 | ||
|
|
b9e44888c0 | ||
|
|
ab84939254 | ||
|
|
722dd4637b | ||
|
|
e6581d52cc | ||
|
|
033abd6d77 | ||
|
|
e120438c8c | ||
|
|
ed4c0245c7 | ||
|
|
9dfa843a38 | ||
|
|
2375d659d7 | ||
|
|
96a6f688cb | ||
|
|
8fccf0bac9 | ||
|
|
8fdc4d8797 | ||
|
|
c9c8f86539 | ||
|
|
4dd3fbfcd2 | ||
|
|
63831d6984 | ||
|
|
d4050f42fd | ||
|
|
53266476e6 | ||
|
|
342d56b23d | ||
|
|
c511e0560f | ||
|
|
acd93dfb6d | ||
|
|
0ddcf2a919 | ||
|
|
7740edae36 | ||
|
|
90ba99a2c2 | ||
|
|
279550ee85 | ||
|
|
c351b47ce8 | ||
|
|
bba11e3255 | ||
|
|
3918e544d8 | ||
|
|
4435161456 | ||
|
|
19f3f4b155 | ||
|
|
1a2ec3fc60 | ||
|
|
e12d69df0c | ||
|
|
69f6aee35c | ||
|
|
00b50850eb | ||
|
|
1b1f7c627a | ||
|
|
1fc80d0ca7 | ||
|
|
e797db8909 | ||
|
|
29ee694341 | ||
|
|
9580fcfedd | ||
|
|
4bb836be20 | ||
|
|
087150de95 | ||
|
|
5b5f99ef18 | ||
|
|
d017c4bf3a | ||
|
|
d9d181e5ad | ||
|
|
113f1fd6d5 | ||
|
|
067852ca61 | ||
|
|
5515937073 | ||
|
|
b9d1dc329f | ||
|
|
4fd66387a9 | ||
|
|
73e2dd3381 | ||
|
|
9e1da42af1 | ||
|
|
7b4993dd16 | ||
|
|
fc904569ea | ||
|
|
5d76185792 | ||
|
|
4b8f411d31 | ||
|
|
f842b8f4be | ||
|
|
fdbfcc0b51 | ||
|
|
79a4339f1b | ||
|
|
8bd58502ca | ||
|
|
a3b4f8320d | ||
|
|
68b5dd2ba9 | ||
|
|
6545a5c234 | ||
|
|
eb4e4b7bca | ||
|
|
daf9357d27 | ||
|
|
919bd3eb0c | ||
|
|
89e613cf01 | ||
|
|
7dd871438f | ||
|
|
beb767dbe0 | ||
|
|
a5415456d4 | ||
|
|
31ada13463 | ||
|
|
45e2dc692b | ||
|
|
be5d389768 | ||
|
|
234df7d2ca | ||
|
|
4bc7a91be7 | ||
|
|
6150d9342c | ||
|
|
d25cc7f090 | ||
|
|
69b999eb7e | ||
|
|
9ba0654ad7 | ||
|
|
36fef6dcd9 | ||
|
|
9028846c63 | ||
|
|
2a24763f6c | ||
|
|
7561e6b6e3 | ||
|
|
297baa0c18 | ||
|
|
82640b7363 | ||
|
|
fd8a70b1ee | ||
|
|
c895fbea22 | ||
|
|
76bd799eb7 | ||
|
|
b7d83ff8a6 | ||
|
|
c34fd92466 | ||
|
|
a8ac22452d | ||
|
|
cc3587f4a3 | ||
|
|
9990089f28 | ||
|
|
79c66e7cd2 | ||
|
|
64774c7ddb | ||
|
|
fe5f5d40f2 | ||
|
|
49e31265ed | ||
|
|
c7f074b163 | ||
|
|
71e200b338 | ||
|
|
b24640f463 | ||
|
|
b8dd98178c | ||
|
|
24a88e3906 | ||
|
|
2b3ea0a2bd | ||
|
|
da3d6f3d64 | ||
|
|
cce9550e48 | ||
|
|
47acdcb176 | ||
|
|
13a218d328 | ||
|
|
c5659cb8bd | ||
|
|
deadeeae1d | ||
|
|
44079a0c82 | ||
|
|
0ede82d466 | ||
|
|
2297a9aa01 | ||
|
|
8b98ffea5f | ||
|
|
35d90d3858 | ||
|
|
6eab2b9101 | ||
|
|
b4db856d37 | ||
|
|
9139d031d8 | ||
|
|
5e8359d360 | ||
|
|
08684a9828 | ||
|
|
0e7987c61a | ||
|
|
cc91072f0e | ||
|
|
0146505187 | ||
|
|
88527e4569 | ||
|
|
3c925b18fa | ||
|
|
50756b515c | ||
|
|
e7ddcbcb86 | ||
|
|
190f4f9f18 | ||
|
|
26babfb357 | ||
|
|
3ab7734b88 | ||
|
|
510676fbbf | ||
|
|
69bc61de41 | ||
|
|
af9c6afa6f | ||
|
|
41537cdddc | ||
|
|
de656f8a49 | ||
|
|
51c1cc4ff5 | ||
|
|
fa3a01374d | ||
|
|
cc70ec1e67 | ||
|
|
2bcc8d8394 | ||
|
|
f4748ff9ff | ||
|
|
29edee4e70 | ||
|
|
05711d9961 | ||
|
|
25e3560546 | ||
|
|
22b9f16e9a | ||
|
|
1ff04117c3 | ||
|
|
65eaab52b6 | ||
|
|
5feb96520a | ||
|
|
918466c262 | ||
|
|
e4e39d852a | ||
|
|
24babb0194 | ||
|
|
bbcee18b4b | ||
|
|
be5242e0fe | ||
|
|
e995ad1131 | ||
|
|
b79e9044f9 | ||
|
|
c1639b3e52 | ||
|
|
3794431b78 | ||
|
|
7e5bd4ec69 | ||
|
|
270df3ffd6 | ||
|
|
e75e003ae4 | ||
|
|
cefa310cf9 | ||
|
|
ec3d25fcbd | ||
|
|
5b295bf191 | ||
|
|
c03ac47baf | ||
|
|
062284e4fb | ||
|
|
9b4d9ac6c7 | ||
|
|
3639942891 | ||
|
|
dc61a5c359 | ||
|
|
87c055e95e | ||
|
|
9053b8a4d4 | ||
|
|
b0089e3c2f | ||
|
|
9ce03bc7da | ||
|
|
56b3eda377 | ||
|
|
23a408a51b | ||
|
|
f025482678 | ||
|
|
28dcdb2d13 | ||
|
|
6ee2dc47f3 | ||
|
|
4a836ced7e | ||
|
|
504448bce3 | ||
|
|
d61a12799c | ||
|
|
4d54c4bdf0 | ||
|
|
801080cf7e | ||
|
|
de4fff0fb3 | ||
|
|
1803228597 | ||
|
|
411984c0e9 | ||
|
|
ef2a2fa3a1 | ||
|
|
242387e51b | ||
|
|
d7229b2bb6 | ||
|
|
b8368a7bcf | ||
|
|
6fcf7ede49 | ||
|
|
a741d3b266 | ||
|
|
0f3448ef8b | ||
|
|
63a450281a | ||
|
|
e011f0ca60 | ||
|
|
55936dc23d | ||
|
|
da40b116a6 | ||
|
|
3dec59f00d | ||
|
|
bafe6a9f7a | ||
|
|
dfdc19fb2a | ||
|
|
27629577b0 | ||
|
|
d410b23f90 | ||
|
|
3e5a4c6f30 | ||
|
|
6c6b356f63 | ||
|
|
e0b247bc87 | ||
|
|
37d5a2b18f | ||
|
|
fa1c26f022 | ||
|
|
2916a14018 | ||
|
|
07670ff871 | ||
|
|
795cb98ac6 | ||
|
|
362c87f4b0 | ||
|
|
0acafba89d | ||
|
|
75bc207653 | ||
|
|
0929b7a4e4 | ||
|
|
2be895e4fe | ||
|
|
52686b3226 | ||
|
|
e853fec3fd | ||
|
|
d5fb8e5830 | ||
|
|
1137d9cb2b | ||
|
|
52d2ead59d | ||
|
|
47388e6362 | ||
|
|
dd551706a9 | ||
|
|
0cfd77185b | ||
|
|
3af83e196c | ||
|
|
3ca381ee8b | ||
|
|
f67bd30131 | ||
|
|
8525c40eac | ||
|
|
6932bbfd52 | ||
|
|
bdb18d9f48 | ||
|
|
24972fa986 | ||
|
|
f0e67720d4 | ||
|
|
afe01e4956 | ||
|
|
8c5e2e66bc | ||
|
|
d748c9f990 | ||
|
|
8c9e254319 | ||
|
|
5606466624 | ||
|
|
0d27b3ea69 | ||
|
|
2b5bffe6c7 | ||
|
|
a80f0b982a | ||
|
|
68694e3141 | ||
|
|
22f1c8a062 | ||
|
|
b28e3d01d7 | ||
|
|
a3beb42ded | ||
|
|
3d9f460313 | ||
|
|
a1abdba1eb | ||
|
|
cfa1028d7e | ||
|
|
2109f5bfe3 | ||
|
|
feadaaed56 | ||
|
|
4fb998d42f | ||
|
|
7b8222aa44 | ||
|
|
528e4166a6 | ||
|
|
ff91a48f6e | ||
|
|
503f8193e8 | ||
|
|
2728e6f017 | ||
|
|
836a5dfddb | ||
|
|
6d9c9f8f04 | ||
|
|
646b4cca85 | ||
|
|
b85b87fabc | ||
|
|
47a1447cc8 | ||
|
|
bb3d43fa05 | ||
|
|
3e4cef131e | ||
|
|
f9ba0a157f | ||
|
|
71b63fc701 | ||
|
|
88eb7ea47d | ||
|
|
2142d78281 | ||
|
|
ddb207e7fa | ||
|
|
d1e030db02 | ||
|
|
9aa9014523 | ||
|
|
44035de79f | ||
|
|
fb35d7c56e | ||
|
|
71ba533640 | ||
|
|
4773c1dfdc | ||
|
|
8615e42942 | ||
|
|
c812ee9c35 | ||
|
|
287c91c1f0 | ||
|
|
ab0939e5e5 | ||
|
|
56754a7f9e | ||
|
|
88412772d2 | ||
|
|
7acba332fe | ||
|
|
449fd307e4 | ||
|
|
d5ce62c17c | ||
|
|
a5607c4b5a | ||
|
|
c96a6b4493 | ||
|
|
37a685ff2b | ||
|
|
1486a9ebf7 | ||
|
|
e19c789979 | ||
|
|
3445e0e59e | ||
|
|
3e13c6dcb2 | ||
|
|
8aa952410a | ||
|
|
b73ef0ee4a | ||
|
|
c2cce33cba | ||
|
|
82b07b62c0 | ||
|
|
a88feb139c | ||
|
|
30f8a9baff | ||
|
|
63fd969300 | ||
|
|
59f39dea66 | ||
|
|
9dfc5d5511 | ||
|
|
e72b00b1ec | ||
|
|
f4f9e39faa | ||
|
|
0bcb32ae47 | ||
|
|
a54de936d0 | ||
|
|
31b6024c65 | ||
|
|
a7918213e7 | ||
|
|
eeafa4e518 | ||
|
|
ca7f2f5f43 | ||
|
|
b426897c9c | ||
|
|
96de7c4b0a | ||
|
|
72bd28a5da | ||
|
|
8a3b41cd39 | ||
|
|
cac55bad1a | ||
|
|
f92c9b3ced | ||
|
|
061cb9b807 | ||
|
|
d0e51f5ce9 | ||
|
|
9db6a93b69 | ||
|
|
07bbe62742 | ||
|
|
fa89d8b3f9 | ||
|
|
aec519199b | ||
|
|
09f9403a6e | ||
|
|
0ef8b4caf3 | ||
|
|
89a0d3c2b2 | ||
|
|
eabcdb2eb2 | ||
|
|
3bd8ac6710 | ||
|
|
92f108801e | ||
|
|
d319a0c1d8 | ||
|
|
df9078ea55 | ||
|
|
6f634ebb8c | ||
|
|
bcda6c9392 | ||
|
|
d21602c072 | ||
|
|
648673bffe | ||
|
|
106fab00bc | ||
|
|
aa679295e4 | ||
|
|
f66013df94 | ||
|
|
4b3a11debb | ||
|
|
4e8c876120 | ||
|
|
8bc2881260 | ||
|
|
a0420a72af | ||
|
|
f545ef48eb | ||
|
|
e331f9af73 | ||
|
|
556ed2d3f4 | ||
|
|
6f584e22fe | ||
|
|
2422c70c4f | ||
|
|
699497e99f | ||
|
|
abd75ea2c5 | ||
|
|
fb76316819 | ||
|
|
8b6d707df0 | ||
|
|
2f6317c483 | ||
|
|
38e981bbdc | ||
|
|
bedd503c3f | ||
|
|
9cc73b5c75 | ||
|
|
c55dbad546 | ||
|
|
f48fc67c86 | ||
|
|
62465b6d82 | ||
|
|
19cdad194b | ||
|
|
79ca53b62b | ||
|
|
b386991471 | ||
|
|
61d29990b4 | ||
|
|
136dd53ac2 | ||
|
|
9d96cde268 | ||
|
|
0e5f475f5e | ||
|
|
0874ef624c | ||
|
|
046c345de5 | ||
|
|
490aa1f984 | ||
|
|
0e18003374 | ||
|
|
ef0eed7f5f | ||
|
|
5b08e56eca | ||
|
|
0cc2600ec6 | ||
|
|
26ff3a4c1e | ||
|
|
56da3638c4 | ||
|
|
d67c05bb89 | ||
|
|
8617f2fa8d | ||
|
|
93288d0095 | ||
|
|
323e59adfc | ||
|
|
79e05bf557 | ||
|
|
200e407b24 | ||
|
|
25e65a7599 | ||
|
|
15ba757a2b | ||
|
|
f41a7b926a | ||
|
|
2cf94189a2 | ||
|
|
4e7b31a0db | ||
|
|
8af0870d72 | ||
|
|
7a529790b2 | ||
|
|
d7b01aff89 | ||
|
|
7911b6405c | ||
|
|
cfe8a8b968 | ||
|
|
26f4e40622 | ||
|
|
3e6f176733 | ||
|
|
7cbd8f8b8a | ||
|
|
f584b67eaa | ||
|
|
7319298ffe | ||
|
|
17759439d7 | ||
|
|
df4d559881 | ||
|
|
7f1239232e | ||
|
|
cc3849f039 | ||
|
|
1a2a8c6d4e | ||
|
|
70ff3ad7d1 | ||
|
|
859913f6d4 | ||
|
|
91d3cd8559 | ||
|
|
231a311ecb | ||
|
|
46aa2c396b | ||
|
|
7e16bb263f | ||
|
|
87a37f4090 | ||
|
|
0c982798e0 | ||
|
|
2c6ecbbea1 | ||
|
|
8cd23d49db | ||
|
|
d89b1dad8a | ||
|
|
813830e763 | ||
|
|
c0b83ba2be | ||
|
|
a8e84b1b21 | ||
|
|
ef39f40445 | ||
|
|
fcbe20d357 | ||
|
|
b183494f37 | ||
|
|
16b4167fdd | ||
|
|
e6105ffb22 | ||
|
|
2711948d14 | ||
|
|
9469db9311 | ||
|
|
71c39612d5 | ||
|
|
5d299509b4 | ||
|
|
16e2d954fc | ||
|
|
b465f00d42 | ||
|
|
00e99dcafd | ||
|
|
2bfe92c90f | ||
|
|
28ed0119ac | ||
|
|
408b172017 | ||
|
|
d19356948a | ||
|
|
97cab239d7 | ||
|
|
bf046d6d66 | ||
|
|
efa7f87de4 | ||
|
|
aeb7508959 | ||
|
|
6e698f1fa5 | ||
|
|
7beb17f2fd | ||
|
|
1ad0287499 | ||
|
|
c30c40c359 | ||
|
|
5ba53cac06 | ||
|
|
67787d7b6d | ||
|
|
a4c4c3593b | ||
|
|
2bd1a74690 | ||
|
|
abafb7b4f9 | ||
|
|
9bd171888b | ||
|
|
adf8f0f284 | ||
|
|
d27f3e7b64 | ||
|
|
44921ca75d | ||
|
|
8d2de21b1c | ||
|
|
0d776ef87b | ||
|
|
213d9ee62d | ||
|
|
8673394ecc | ||
|
|
60dda65306 | ||
|
|
3e9a31748d | ||
|
|
acd7fcf55f | ||
|
|
31e27fc89a | ||
|
|
831bb9260c | ||
|
|
3d6d863ccb | ||
|
|
3b81337f80 | ||
|
|
79ea51f360 | ||
|
|
beb9520039 | ||
|
|
92fe2d0a85 | ||
|
|
e2329bc704 | ||
|
|
1765548bce | ||
|
|
876792c756 | ||
|
|
7f9e036077 | ||
|
|
ca635e4884 | ||
|
|
bbeccd7474 | ||
|
|
8312836c74 | ||
|
|
7958793342 | ||
|
|
e64da8c20d | ||
|
|
308c0a727e | ||
|
|
5e977e69e1 | ||
|
|
6213d9fc91 | ||
|
|
5d9403f56c | ||
|
|
24ed330a22 | ||
|
|
b8470e19e4 | ||
|
|
00525b824a | ||
|
|
a410067d78 | ||
|
|
47bc380ecf | ||
|
|
ad0b63cad4 | ||
|
|
8cac75969e | ||
|
|
7f0f04e606 | ||
|
|
e8780e27fd | ||
|
|
24b41a23b3 | ||
|
|
e0e990229d | ||
|
|
a390d579bb | ||
|
|
6dc6daf7e3 | ||
|
|
3411fe33a2 | ||
|
|
2775dc2b44 | ||
|
|
29d8aad2f6 | ||
|
|
0cb365fb98 | ||
|
|
05c73757ed | ||
|
|
bcdbd47117 | ||
|
|
fdfc31a4f7 | ||
|
|
13280a9e36 | ||
|
|
69ea7f9509 | ||
|
|
8ff79d3e89 | ||
|
|
0b89bb83ba | ||
|
|
dff820cea3 | ||
|
|
cccc75eef9 | ||
|
|
554b30389e | ||
|
|
c35bb34608 | ||
|
|
6464b3ffae | ||
|
|
4f2563329b | ||
|
|
3b78a24ee9 | ||
|
|
0b648a424f | ||
|
|
3571a68ab9 | ||
|
|
edb2799333 | ||
|
|
bf2f80b223 | ||
|
|
372844918a | ||
|
|
f86b2193a4 | ||
|
|
da7c87e2f8 | ||
|
|
7e9daf60c1 | ||
|
|
b9ac5e23fb | ||
|
|
aca474fa14 | ||
|
|
99f0760bfb | ||
|
|
8d1099ac05 | ||
|
|
4bdd9aabdd | ||
|
|
bdac08bcdd | ||
|
|
d2e1a04b10 | ||
|
|
0cbfdc9df5 | ||
|
|
bc44eb6172 | ||
|
|
03797a73b2 | ||
|
|
9586b15229 | ||
|
|
15c139b99a | ||
|
|
f10d194c8c | ||
|
|
af3bd57d33 | ||
|
|
fa08ff9245 | ||
|
|
b85b78db4f | ||
|
|
b16929ca72 | ||
|
|
bba16dde5d | ||
|
|
582f42b8d4 | ||
|
|
9befa8c5f7 | ||
|
|
9266227402 | ||
|
|
627704b38e | ||
|
|
72c9b0e12b | ||
|
|
592df89027 | ||
|
|
3e7d11b632 | ||
|
|
a734acd439 | ||
|
|
5e95b61639 | ||
|
|
0c6e2b5219 | ||
|
|
70f92aa97e | ||
|
|
fe551c089a | ||
|
|
63f42adbb2 | ||
|
|
af85eff5b6 | ||
|
|
53fa6c5b6b | ||
|
|
834daa455b | ||
|
|
7533243f0c | ||
|
|
47d630e7f0 | ||
|
|
f54451cf39 | ||
|
|
8da58e36b4 | ||
|
|
83bacd2fe0 | ||
|
|
57f82819e9 | ||
|
|
4b9fcc01d4 | ||
|
|
30aceaf1a7 | ||
|
|
197095c29e | ||
|
|
f89b7ec389 | ||
|
|
21446cd7b6 | ||
|
|
e665a07ab9 | ||
|
|
f0ba3e265a | ||
|
|
65c1e14cb9 | ||
|
|
1bf996b324 | ||
|
|
5270ee1aef | ||
|
|
d7368c2531 | ||
|
|
daefca44b5 | ||
|
|
c301467f9b | ||
|
|
13b45a36f0 | ||
|
|
210e35a2fa | ||
|
|
49d6472f9f | ||
|
|
cd38d72eee | ||
|
|
08c63e2a56 | ||
|
|
e55c641792 | ||
|
|
b206b0e29d | ||
|
|
ee275e34c8 | ||
|
|
a8b97086d7 | ||
|
|
b38ca3adee | ||
|
|
302ccc195b | ||
|
|
fc5f931663 | ||
|
|
db03216e62 | ||
|
|
30a73658c6 | ||
|
|
32be79dcfa | ||
|
|
4d667eeaf3 | ||
|
|
7fac56e072 | ||
|
|
1d6e9e8fb7 | ||
|
|
f39ff29366 | ||
|
|
bd3e758cf8 | ||
|
|
7ec03b481a | ||
|
|
b165be9ae1 | ||
|
|
f7b7c14594 | ||
|
|
86b2d7b523 | ||
|
|
e0a177d676 | ||
|
|
1e1b7c74fb | ||
|
|
52f35b984c | ||
|
|
dbe8c37476 | ||
|
|
cba1150cdb | ||
|
|
437612f656 | ||
|
|
5e338836ff | ||
|
|
32314f6b67 | ||
|
|
8afe869cab | ||
|
|
51be35cf38 | ||
|
|
2659b0f3cb | ||
|
|
660cfeabb4 | ||
|
|
e3605383cd | ||
|
|
44d61576b9 | ||
|
|
18c9f8fbb9 | ||
|
|
856801b84f | ||
|
|
05955fbce5 | ||
|
|
7efbccd60f | ||
|
|
679d08e8ba | ||
|
|
55d97085a4 | ||
|
|
79230e5561 | ||
|
|
5e6c5e9569 | ||
|
|
b264783d63 | ||
|
|
3200d99763 | ||
|
|
d4b5ef2e4a | ||
|
|
eae7a94fe0 | ||
|
|
a1edc8e396 | ||
|
|
9a8123fabb | ||
|
|
91b599f4a3 | ||
|
|
3e3dcde8d7 | ||
|
|
ea12799eff | ||
|
|
b20abadf90 | ||
|
|
57294d6824 | ||
|
|
2462d2764a | ||
|
|
f1a6ca29fb | ||
|
|
d260b5d240 | ||
|
|
395a936397 | ||
|
|
1deeec0ba8 | ||
|
|
591e64ff58 | ||
|
|
270e487d41 | ||
|
|
137feda86a | ||
|
|
2dd38009ca | ||
|
|
75bad44801 | ||
|
|
2b111a3b14 | ||
|
|
b36bae023e | ||
|
|
868dbe7baf | ||
|
|
36f487a32c | ||
|
|
31c15f0d17 | ||
|
|
02352bee60 | ||
|
|
a1387ae088 | ||
|
|
4350937027 |
No files matched your search
@@ -48,80 +48,110 @@ define print_cvs
|
||||
end
|
||||
|
||||
define dump_bt
|
||||
set $ex = $arg0->prev_execute_data
|
||||
while $ex
|
||||
printf "[%p] ", $ex
|
||||
set $func = $ex->func
|
||||
if $func
|
||||
if $ex->object
|
||||
if $func->common.scope
|
||||
printf "%s->", $func->common.scope->name->val
|
||||
set $t = $arg0
|
||||
while $t
|
||||
printf "[%p] ", $t
|
||||
set $fst = $t->function_state
|
||||
if $fst.function->common.function_name
|
||||
if $fst.arguments
|
||||
set $count = (int)*($fst.arguments)
|
||||
|
||||
if $t->object
|
||||
if $fst.function.common.scope
|
||||
printf "%s->", $fst.function.common.scope->name
|
||||
else
|
||||
if !$eg
|
||||
____executor_globals
|
||||
end
|
||||
|
||||
set $known_class = 0
|
||||
if $eg
|
||||
set $handle = $t->object.value.obj.handle
|
||||
set $handlers = $t->object.value.obj.handlers
|
||||
set $zobj = (zend_object *)$eg.objects_store.object_buckets[$handle].bucket.obj.object
|
||||
|
||||
if $handlers->get_class_entry == &zend_std_object_get_class
|
||||
set $known_class = 1
|
||||
|
||||
if $handlers.get_class_name
|
||||
if $handlers.get_class_name != &zend_std_object_get_class_name
|
||||
set $known_class = 0
|
||||
end
|
||||
end
|
||||
|
||||
if $known_class
|
||||
printf "%s->", $zobj->ce.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !$known_class
|
||||
printf "(Unknown)->"
|
||||
end
|
||||
end
|
||||
else
|
||||
printf "%s->", $ex->object->ce.name->val
|
||||
if $fst.function.common.scope
|
||||
printf "%s::", $fst.function.common.scope->name
|
||||
end
|
||||
end
|
||||
|
||||
printf "%s(", $fst.function->common.function_name
|
||||
while $count > 0
|
||||
set $zvalue = *(zval **)($fst.arguments - $count)
|
||||
set $type = $zvalue->type
|
||||
if $type == 0
|
||||
printf "NULL"
|
||||
end
|
||||
if $type == 1
|
||||
printf "%ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 2
|
||||
printf "%f", $zvalue->value.dval
|
||||
end
|
||||
if $type == 3
|
||||
if $zvalue->value.lval
|
||||
printf "true"
|
||||
else
|
||||
printf "false"
|
||||
end
|
||||
end
|
||||
if $type == 4
|
||||
printf "array(%d)[%p]", $zvalue->value.ht->nNumOfElements, $zvalue
|
||||
end
|
||||
if $type == 5
|
||||
printf "object[%p]", $zvalue
|
||||
end
|
||||
if $type == 6
|
||||
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
||||
end
|
||||
if $type == 7
|
||||
printf "resource(#%d)", $zvalue->value.lval
|
||||
end
|
||||
if $type == 8
|
||||
printf "constant"
|
||||
end
|
||||
if $type == 9
|
||||
printf "const_array"
|
||||
end
|
||||
if $type > 9
|
||||
printf "unknown type %d", $type
|
||||
end
|
||||
set $count = $count -1
|
||||
if $count > 0
|
||||
printf ", "
|
||||
end
|
||||
end
|
||||
printf ") "
|
||||
else
|
||||
if $func->common.scope
|
||||
printf "%s::", $func->common.scope->name->val
|
||||
end
|
||||
printf "%s() ", $fst.function->common.function_name
|
||||
end
|
||||
|
||||
printf "%s(", $func->common.function_name->val
|
||||
|
||||
set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)
|
||||
|
||||
set $count = $ex->num_args
|
||||
set $arg = 0
|
||||
while $arg < $count
|
||||
if $arg > 0
|
||||
printf ", "
|
||||
end
|
||||
|
||||
set $zvalue = (zval *) $ex + $callFrameSize + $arg
|
||||
set $type = $zvalue->u1.v.type
|
||||
if $type == 1
|
||||
printf "NULL"
|
||||
end
|
||||
if $type == 2
|
||||
printf "false"
|
||||
end
|
||||
if $type == 3
|
||||
printf "true"
|
||||
end
|
||||
if $type == 4
|
||||
printf "%ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 5
|
||||
printf "%f", $zvalue->value.dval
|
||||
end
|
||||
if $type == 6
|
||||
____print_str $zvalue->value.str->val $zvalue->value.str->len
|
||||
end
|
||||
if $type == 7
|
||||
printf "array(%d)[%p]", $zvalue->value.arr->ht->nNumOfElements, $zvalue
|
||||
end
|
||||
if $type == 8
|
||||
printf "object[%p]", $zvalue
|
||||
end
|
||||
if $type == 9
|
||||
printf "resource(#%d)", $zvalue->value.lval
|
||||
end
|
||||
if $type == 10
|
||||
printf "reference"
|
||||
end
|
||||
if $type > 10
|
||||
printf "unknown type %d", $type
|
||||
end
|
||||
set $arg = $arg + 1
|
||||
end
|
||||
|
||||
printf ") "
|
||||
else
|
||||
printf "??? "
|
||||
end
|
||||
if $func != 0
|
||||
printf "%s:%d ", $func->op_array.filename->val, $ex->opline->lineno
|
||||
if $t->op_array != 0
|
||||
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
|
||||
end
|
||||
set $ex = $ex->prev_execute_data
|
||||
set $t = $t->prev_execute_data
|
||||
printf "\n"
|
||||
end
|
||||
end
|
||||
@@ -141,37 +171,34 @@ end
|
||||
|
||||
define ____printzv_contents
|
||||
set $zvalue = $arg0
|
||||
set $type = $zvalue->u1.v.type
|
||||
set $type = $zvalue->type
|
||||
|
||||
# 15 == IS_INDIRECT
|
||||
if $type >= 5 && $type != 15
|
||||
printf "(refcount=%d) ", $zvalue->value.counted->refcount
|
||||
printf "(refcount=%d", $zvalue->refcount__gc
|
||||
if $zvalue->is_ref__gc
|
||||
printf ",is_ref"
|
||||
end
|
||||
|
||||
printf ") "
|
||||
if $type == 0
|
||||
printf "UNDEF"
|
||||
printf "NULL"
|
||||
end
|
||||
if $type == 1
|
||||
printf "NULL"
|
||||
printf "long: %ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 2
|
||||
printf "bool: false"
|
||||
printf "double: %f", $zvalue->value.dval
|
||||
end
|
||||
if $type == 3
|
||||
printf "bool: true"
|
||||
printf "bool: "
|
||||
if $zvalue->value.lval
|
||||
printf "true"
|
||||
else
|
||||
printf "false"
|
||||
end
|
||||
end
|
||||
if $type == 4
|
||||
printf "long: %ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 5
|
||||
printf "double: %f", $zvalue->value.dval
|
||||
end
|
||||
if $type == 6
|
||||
printf "string: %s", $zvalue->value.str->val
|
||||
end
|
||||
if $type == 7
|
||||
printf "array: "
|
||||
if $type == 4
|
||||
printf "array(%d): ", $zvalue->value.ht->nNumOfElements
|
||||
if ! $arg1
|
||||
printf "{\n"
|
||||
set $ind = $ind + 1
|
||||
____print_ht $zvalue->value.ht 1
|
||||
set $ind = $ind - 1
|
||||
@@ -180,21 +207,32 @@ define ____printzv_contents
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
printf "}"
|
||||
end
|
||||
set $type = 0
|
||||
end
|
||||
if $type == 8
|
||||
if $type == 5
|
||||
printf "object"
|
||||
____executor_globals
|
||||
set $handle = $zvalue->value.obj.handle
|
||||
set $handlers = $zvalue->value.obj.handlers
|
||||
set $zobj = $zvalue->value.obj
|
||||
set $cname = $zobj->ce->name->val
|
||||
if basic_functions_module.zts
|
||||
set $zobj = zend_objects_get_address($zvalue, $tsrm_ls)
|
||||
else
|
||||
set $zobj = zend_objects_get_address($zvalue)
|
||||
end
|
||||
if $handlers->get_class_entry == &zend_std_object_get_class
|
||||
set $cname = $zobj->ce.name
|
||||
else
|
||||
set $cname = "Unknown"
|
||||
end
|
||||
printf "(%s) #%d", $cname, $handle
|
||||
if ! $arg1
|
||||
if $handlers->get_properties == &zend_std_get_properties
|
||||
set $ht = $zobj->properties
|
||||
if $ht
|
||||
printf "(%d): ", $ht->nNumOfElements
|
||||
printf "{\n"
|
||||
set $ind = $ind + 1
|
||||
____print_ht $ht 1
|
||||
set $ind = $ind - 1
|
||||
@@ -203,6 +241,7 @@ define ____printzv_contents
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
printf "}"
|
||||
else
|
||||
echo "no properties found"
|
||||
end
|
||||
@@ -210,36 +249,20 @@ define ____printzv_contents
|
||||
end
|
||||
set $type = 0
|
||||
end
|
||||
if $type == 6
|
||||
printf "string(%d): ", $zvalue->value.str.len
|
||||
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
||||
end
|
||||
if $type == 7
|
||||
printf "resource: #%d", $zvalue->value.lval
|
||||
end
|
||||
if $type == 8
|
||||
printf "constant"
|
||||
end
|
||||
if $type == 9
|
||||
printf "resource: #%d", $zvalue->value.res->handle
|
||||
printf "const_array"
|
||||
end
|
||||
if $type == 10
|
||||
printf "reference: "
|
||||
____printzv &$zvalue->value.ref->val $arg1
|
||||
end
|
||||
if $type == 11
|
||||
printf "const: %s", $zvalue->value.str->val
|
||||
end
|
||||
if $type == 12
|
||||
printf "const_ast"
|
||||
end
|
||||
if $type == 13
|
||||
printf "_IS_BOOL"
|
||||
end
|
||||
if $type == 14
|
||||
printf "IS_CALLABLE"
|
||||
end
|
||||
if $type == 15
|
||||
printf "indirect: "
|
||||
____printzv $zvalue->value.zv $arg1
|
||||
end
|
||||
if $type == 16
|
||||
printf "string_offset"
|
||||
end
|
||||
if $type == 17
|
||||
printf "pointer: %p", $zvalue->value.ptr
|
||||
end
|
||||
if $type > 17
|
||||
if $type > 9
|
||||
printf "unknown type %d", $type
|
||||
end
|
||||
printf "\n"
|
||||
@@ -251,6 +274,10 @@ define ____printzv
|
||||
|
||||
printf "[%p] ", $zvalue
|
||||
|
||||
if $zvalue == $eg.uninitialized_zval_ptr
|
||||
printf "*uninitialized* "
|
||||
end
|
||||
|
||||
set $zcontents = (zval*) $zvalue
|
||||
if $arg1
|
||||
____printzv_contents $zcontents $arg1
|
||||
@@ -293,60 +320,42 @@ end
|
||||
|
||||
define ____print_ht
|
||||
set $ht = (HashTable*)$arg0
|
||||
set $n = $ind
|
||||
while $n > 0
|
||||
printf " "
|
||||
set $n = $n - 1
|
||||
end
|
||||
set $p = $ht->pListHead
|
||||
|
||||
if $ht->u.v.flags & 4
|
||||
printf "Packed"
|
||||
else
|
||||
printf "Hash"
|
||||
end
|
||||
printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht
|
||||
|
||||
set $num = $ht->nNumUsed
|
||||
set $i = 0
|
||||
set $ind = $ind + 1
|
||||
while $i < $num
|
||||
set $p = (Bucket*)($ht->arData + $i)
|
||||
set $n = $ind
|
||||
if $p->val.u1.v.type > 0
|
||||
while $n > 0
|
||||
printf " "
|
||||
set $n = $n - 1
|
||||
end
|
||||
printf "[%d] ", $i
|
||||
if $p->key
|
||||
printf "%s => ", $p->key->val
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
if $arg1 == 0
|
||||
printf "%p\n", (zval *)&$p->val
|
||||
end
|
||||
if $arg1 == 1
|
||||
set $zval = (zval *)&$p->val
|
||||
____printzv $zval 1
|
||||
end
|
||||
if $arg1 == 2
|
||||
printf "%s\n", (char*)$p->val.value.ptr
|
||||
end
|
||||
if $arg1 == 3
|
||||
set $func = (zend_function*)$p->val.value.ptr
|
||||
printf "\"%s\"\n", $func->common.function_name->val
|
||||
end
|
||||
while $p != 0
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
set $i = $i + 1
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
____print_str $p->arKey $p->nKeyLength
|
||||
printf " => "
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
if $arg1 == 0
|
||||
printf "%p\n", (void*)$p->pData
|
||||
end
|
||||
if $arg1 == 1
|
||||
set $zval = *(zval **)$p->pData
|
||||
____printzv $zval 1
|
||||
end
|
||||
if $arg1 == 2
|
||||
printf "%s\n", (char*)$p->pData
|
||||
end
|
||||
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
set $ind = $ind - 1
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
define print_ht
|
||||
set $ind = 0
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 1
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_ht
|
||||
@@ -354,8 +363,10 @@ document print_ht
|
||||
end
|
||||
|
||||
define print_htptr
|
||||
set $ind = 0
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_htptr
|
||||
@@ -363,17 +374,46 @@ document print_htptr
|
||||
end
|
||||
|
||||
define print_htstr
|
||||
set $ind = 0
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 2
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_htstr
|
||||
dumps elements of HashTable made of strings
|
||||
end
|
||||
|
||||
define ____print_ft
|
||||
set $ht = $arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $func = (zend_function*)$p->pData
|
||||
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
____print_str $p->arKey $p->nKeyLength
|
||||
printf " => "
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
printf "\"%s\"\n", $func->common.function_name
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_ft
|
||||
set $ind = 0
|
||||
____print_ht $arg0 3
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ft $arg0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_ft
|
||||
@@ -389,15 +429,15 @@ define ____print_inh_class
|
||||
printf "final "
|
||||
end
|
||||
end
|
||||
printf "class %s", $ce->name->val
|
||||
printf "class %s", $ce->name
|
||||
if $ce->parent != 0
|
||||
printf " extends %s", $ce->parent->name->val
|
||||
printf " extends %s", $ce->parent->name
|
||||
end
|
||||
if $ce->num_interfaces != 0
|
||||
printf " implements"
|
||||
set $tmp = 0
|
||||
while $tmp < $ce->num_interfaces
|
||||
printf " %s", $ce->interfaces[$tmp]->name->val
|
||||
printf " %s", $ce->interfaces[$tmp]->name
|
||||
set $tmp = $tmp + 1
|
||||
if $tmp < $ce->num_interfaces
|
||||
printf ","
|
||||
@@ -409,10 +449,10 @@ end
|
||||
|
||||
define ____print_inh_iface
|
||||
set $ce = $arg0
|
||||
printf "interface %s", $ce->name->val
|
||||
printf "interface %s", $ce->name
|
||||
if $ce->num_interfaces != 0
|
||||
set $ce = $ce->interfaces[0]
|
||||
printf " extends %s", $ce->name->val
|
||||
printf " extends %s", $ce->name
|
||||
else
|
||||
set $ce = 0
|
||||
end
|
||||
@@ -476,7 +516,7 @@ define ____print_str
|
||||
set $tmp = 0
|
||||
set $str = $arg0
|
||||
printf "\""
|
||||
while $tmp < $arg1 && $tmp < 256
|
||||
while $tmp < $arg1
|
||||
if $str[$tmp] > 32 && $str[$tmp] < 127
|
||||
printf "%c", $str[$tmp]
|
||||
else
|
||||
@@ -484,9 +524,6 @@ define ____print_str
|
||||
end
|
||||
set $tmp = $tmp + 1
|
||||
end
|
||||
if $tmp != $arg1
|
||||
printf "..."
|
||||
end
|
||||
printf "\""
|
||||
end
|
||||
|
||||
@@ -581,9 +618,9 @@ define zmemcheck
|
||||
if $p->magic == 0xfb8277dc
|
||||
set $stat = "CACHED"
|
||||
end
|
||||
set $filename = strrchr($p->filename->val, '/')
|
||||
set $filename = strrchr($p->filename, '/')
|
||||
if !$filename
|
||||
set $filename = $p->filename->val
|
||||
set $filename = $p->filename
|
||||
else
|
||||
set $filename = $filename + 1
|
||||
end
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*.tgz
|
||||
*.tar.gz
|
||||
*.tar.bz2
|
||||
*.tar.xz
|
||||
.FBCIndex
|
||||
.FBCLockFolder
|
||||
.deps
|
||||
|
||||
+3
-9
@@ -1,12 +1,4 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
# We only specify one version so we only get one worker
|
||||
- 5.4
|
||||
|
||||
branches:
|
||||
except:
|
||||
- phpng
|
||||
language: c
|
||||
|
||||
notifications:
|
||||
email:
|
||||
@@ -33,6 +25,7 @@ before_install:
|
||||
- sudo apt-get install -y libenchant-dev libaspell-dev libpspell-dev librecode-dev
|
||||
- sudo cp ./travis/de /var/lib/locales/supported.d/de
|
||||
- sudo dpkg-reconfigure locales
|
||||
- ./travis/install.sh
|
||||
|
||||
before_script:
|
||||
# Compile PHP
|
||||
@@ -47,3 +40,4 @@ before_script:
|
||||
# Run PHPs run-tests.php
|
||||
script:
|
||||
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120
|
||||
- ./sapi/cli/php sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg sapi/phpdbg/phpdbg
|
||||
+1
-1
@@ -42,7 +42,7 @@ Exceptions:
|
||||
|
||||
4. When writing functions that deal with strings, be sure to remember
|
||||
that PHP holds the length property of each string, and that it
|
||||
shouldn't be calculated with strlen(). Write your functions in a such
|
||||
shouldn't be calculated with strlen(). Write your functions in such
|
||||
a way so that they'll take advantage of the length property, both
|
||||
for efficiency and in order for them to be binary-safe.
|
||||
Functions that change strings and obtain their new lengths while
|
||||
|
||||
+12
@@ -385,6 +385,12 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: hash
|
||||
PRIMARY MAINTAINER: Sara Golemon <pollita@php.net>, Mike Wallner <mike@php.net>, Anatol Belski <ab@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.1.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: iconv
|
||||
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -438,6 +444,12 @@ PRIMARY MAINTAINER: Frank M. Kromann
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: opcache
|
||||
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>, Xinchen Hui <laruence@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
|
||||
@@ -155,7 +155,7 @@ Table of Contents
|
||||
a list of all available options along with short explanations running
|
||||
./configure --help. Our manual documents the different options
|
||||
separately. You will find the core options in the appendix, while the
|
||||
different extension specific options are descibed on the reference
|
||||
different extension specific options are described on the reference
|
||||
pages.
|
||||
|
||||
When PHP is configured, you are ready to build the module and/or
|
||||
|
||||
@@ -45,6 +45,9 @@ Currently we have the following branches in use::
|
||||
|
||||
master The active development branch.
|
||||
|
||||
PHP-5.6 Is used to release the PHP 5.6.x series. This is a current
|
||||
stable version and is open for bugfixes only.
|
||||
|
||||
PHP-5.5 Is used to release the PHP 5.5.x series. This is a current
|
||||
stable version and is open for bugfixes only.
|
||||
|
||||
@@ -59,6 +62,9 @@ Currently we have the following branches in use::
|
||||
|
||||
PHP-4.4 This branch is closed.
|
||||
|
||||
PHP-X.Y.Z These branches are used for the release managers for tagging
|
||||
the releases, hence they are closed to the general public.
|
||||
|
||||
The next few rules are more of a technical nature::
|
||||
|
||||
1. All changes should first go to the lowest branch (i.e. 5.4) and then
|
||||
|
||||
+17
-18
@@ -17,7 +17,7 @@ Online Forums
|
||||
-------------
|
||||
There are several IRC channels where PHP developers are often
|
||||
available to discuss questions. They include #php.pecl and #php.doc
|
||||
on the EFNet network and #winphp-dev on FreeNode.
|
||||
on the EFNet network and #php-dev-win on FreeNode.
|
||||
|
||||
|
||||
PHP Patches
|
||||
@@ -33,27 +33,16 @@ and discuss it on the development mail list internals@lists.php.net.
|
||||
RFC Wiki accounts can be requested on
|
||||
http://wiki.php.net/start?do=register. PHP extension maintainers can
|
||||
be found in the EXTENSIONS file in the PHP source. Mail list
|
||||
subscription is explained on http://php.net/mailing-lists.php.
|
||||
subscription is explained on http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on PHP internal C functions is at
|
||||
http://php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. See
|
||||
https://wiki.php.net/internals for some references. A standard
|
||||
http://www.php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. A standard
|
||||
printed reference is the book "Extending and Embedding PHP" by Sara
|
||||
Golemon.
|
||||
|
||||
The preferred way to propose PHP patch is sending pull request from
|
||||
GitHub: https://github.com/php/php-src
|
||||
|
||||
Fork the official PHP repository and send a pull request. A
|
||||
notification will be sent to the pull request mailing list. Sending a
|
||||
note to PHP Internals list (internals@lists.php.net) may help getting
|
||||
more feedback and quicker turnaround. You can also add pull requests
|
||||
to bug reports at http://bugs.php.net/.
|
||||
|
||||
If you are not using GitHub, attach your patch to a PHP bug and
|
||||
consider sending a notification email about the change to
|
||||
internals@lists.php.net. If the bug is for an extension, also CC the
|
||||
Attach the patch to the PHP bug and consider sending a notification
|
||||
email about the change to internals@lists.php.net. Also CC the
|
||||
extension maintainer. Explain what has been changed by your patch.
|
||||
Test scripts should be included.
|
||||
|
||||
@@ -61,6 +50,16 @@ Please make the mail subject prefix "[PATCH]". If attaching a patch,
|
||||
ensure it has a file extension of ".txt". This is because only MIME
|
||||
attachments of type 'text/*' are accepted.
|
||||
|
||||
The preferred way to propose PHP patch is sending pull request from
|
||||
github.
|
||||
|
||||
https://github.com/php/php-src
|
||||
|
||||
Fork the official PHP repository and send a pull request. A
|
||||
notification will be sent to the pull request mailing list. Sending a
|
||||
note to PHP Internals list (internals@lists.php.net) may help getting
|
||||
more feedback and quicker turnaround. You can also add pull requests
|
||||
to bug reports at http://bugs.php.net/.
|
||||
|
||||
|
||||
PHP Documentation Patches
|
||||
@@ -72,7 +71,7 @@ the PHP mail archives.
|
||||
|
||||
If your change is large, then first discuss it with the mail list
|
||||
phpdoc@lists.php.net. Subscription is explained on
|
||||
http://php.net/mailing-lists.php.
|
||||
http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on contributing to PHP documentation is at
|
||||
http://php.net/dochowto and http://wiki.php.net/doc/howto
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ the original run-tests.php script. server-tests is *not* used by
|
||||
'make test'. server-tests was developed to provide support for
|
||||
testing PHP under it's primary environment, HTTP, and can run the
|
||||
PHP tests under any of the SAPI modules that are direct executables,
|
||||
or are accessable via HTTP.
|
||||
or are accessible via HTTP.
|
||||
|
||||
[New features]
|
||||
----------------
|
||||
@@ -95,7 +95,7 @@ include:
|
||||
$filename full native path to file, will become PATH_TRANSLATED
|
||||
$filepath =dirname($filename)
|
||||
$scriptname this is what will become SCRIPT_NAME unless you override it
|
||||
$docroot the equivelant of DOCUMENT_ROOT under Apache
|
||||
$docroot the equivalent of DOCUMENT_ROOT under Apache
|
||||
$cwd the directory that the test is being initiated from
|
||||
$this->conf all server-tests configuration vars
|
||||
$this->env all environment variables that will get passed to the test
|
||||
@@ -105,7 +105,7 @@ include:
|
||||
This section is also eval'd, and is similar in nature to --ENV--. However,
|
||||
this section is used to build the url used in an HTTP request. Valid values
|
||||
to set in this section would include:
|
||||
SCRIPT_NAME The inital part of the request url
|
||||
SCRIPT_NAME The initial part of the request url
|
||||
PATH_INFO The pathinfo part of a request url
|
||||
FRAGMENT The fragment section of a url (after #)
|
||||
QUERY_STRING The query part of a url (after ?)
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ typedef int ts_rsrc_id;
|
||||
|
||||
/* Define THREAD_T and MUTEX_T */
|
||||
#ifdef TSRM_WIN32
|
||||
# define THREAD_T UINT_PTR
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T CRITICAL_SECTION *
|
||||
#elif defined(GNUPTH)
|
||||
# define THREAD_T pth_t
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$Id$
|
||||
|
||||
PHP X.Y UPGRADE NOTES
|
||||
PHP 5.6 UPGRADE NOTES
|
||||
|
||||
1. Backward Incompatible Changes
|
||||
2. New Features
|
||||
@@ -13,49 +13,302 @@ PHP X.Y UPGRADE NOTES
|
||||
9. Other Changes to Extensions
|
||||
10. New Global Constants
|
||||
11. Changes to INI File Handling
|
||||
12. Windows Support
|
||||
13. Other Changes
|
||||
12. Other Changes
|
||||
|
||||
|
||||
========================================
|
||||
1. Backward Incompatible Changes
|
||||
========================================
|
||||
|
||||
- DBA
|
||||
. dba_delete() now returns false if the key was not found for the inifile
|
||||
handler, too.
|
||||
- Core:
|
||||
By fixing bug #66015 it is no longer possible to overwrite keys in static scalar
|
||||
arrays. Quick example to illustrate:
|
||||
class Test {
|
||||
const FIRST = 1;
|
||||
public $array = array(
|
||||
self::FIRST => 'first',
|
||||
'second',
|
||||
'third'
|
||||
);
|
||||
}
|
||||
Test::$array will have as expected three array keys (1, 2, 3) and no longer
|
||||
two (0, 1). self::FIRST will no longer overwrite 'third' having key 1 then,
|
||||
but will mark the beginning of indexing.
|
||||
|
||||
- JSON:
|
||||
json_decode() no longer accepts non-lowercase variants of lone JSON true,
|
||||
false or null values. For example, True or FALSE will now cause json_decode to
|
||||
return NULL and set an error value you can fetch with json_last_error().
|
||||
This affects JSON texts consisting solely of true, false or null. Text
|
||||
containing non-lowercase values inside JSON arrays or objects has never been
|
||||
accepted.
|
||||
|
||||
- OpenSSL:
|
||||
To prevent man-in-the-middle attacks against encrypted transfers client
|
||||
streams now verify peer certificates by default. Previous versions
|
||||
required users to manually enable peer verification. As a result of this
|
||||
change, existing code using ssl:// or tls:// stream wrappers (e.g.
|
||||
file_get_contents(), fsockopen(), stream_socket_client()) may no longer
|
||||
connect successfully without manually disabling peer verification via the
|
||||
stream context's "verify_peer" setting. Encrypted transfers delegate to
|
||||
operating system certificate stores by default if not overridden via the
|
||||
new openssl.cafile and openssl.cafile ini directives or via call-time SSL
|
||||
context options, so most users should be unaffected by this transparent
|
||||
security enhancement. (https://wiki.php.net/rfc/tls-peer-verification)
|
||||
|
||||
- Mcrypt:
|
||||
The mcrypt_encrypt(), mcrypt_decrypt() and mcrypt_{MODE}() functions no
|
||||
longer accept keys or IVs with incorrect sizes. Furthermore an IV is now
|
||||
required if the used block cipher mode requires it.
|
||||
|
||||
========================================
|
||||
2. New Features
|
||||
========================================
|
||||
|
||||
- Core
|
||||
. Support for strings with length >= 2^31 bytes in 64 bit builds
|
||||
- Added constant scalar expressions syntax.
|
||||
(https://wiki.php.net/rfc/const_scalar_exprs)
|
||||
|
||||
- Standard
|
||||
. intdiv() function for integer division added.
|
||||
- Added dedicated syntax for variadic functions.
|
||||
(https://wiki.php.net/rfc/variadics)
|
||||
|
||||
- Added support for argument unpacking to complement the variadic syntax.
|
||||
(https://wiki.php.net/rfc/argument_unpacking)
|
||||
|
||||
- Added an exponentiation operator (**).
|
||||
(https://wiki.php.net/rfc/pow-operator)
|
||||
|
||||
- Added unified default encoding. default_charset=UTF-8 and functions/extensions
|
||||
use encoding settings honor default_charset.
|
||||
|
||||
- The php://input stream is now re-usable and can be used concurrently with
|
||||
enable_post_data_reading=0.
|
||||
|
||||
- Added use function and use const.
|
||||
(https://wiki.php.net/rfc/use_function)
|
||||
|
||||
- Added a function for timing attack safe string comparison
|
||||
(https://wiki.php.net/rfc/timing_attack)
|
||||
|
||||
- Added the __debugInfo() magic method to allow userland classes to implement
|
||||
the get_debug_info API previously available only to extensions.
|
||||
(https://wiki.php.net/rfc/debug-info)
|
||||
|
||||
- Added gost-crypto (CryptoPro S-box) hash algorithm.
|
||||
|
||||
- Stream wrappers verify peer certificates and host names by default in
|
||||
encrypted client streams.
|
||||
|
||||
- Added openssl certificate fingerprint support (inclusive stream context
|
||||
option).
|
||||
|
||||
- Added support for SAN x509 extension matching when verifing host names in
|
||||
encrypted streams.
|
||||
|
||||
- Added a range of new SSL context options for improved encrypted stream
|
||||
server security (https://wiki.php.net/rfc/improved-tls-defaults):
|
||||
|
||||
. "honor_cipher_order" allows servers to prioritize cipher suites of their
|
||||
choosing when negotiating SSL/TLS handshakes.
|
||||
. "single_ecdh_use" and "single_dh_use" allow for improved forward
|
||||
secrecy in encrypted stream servers.
|
||||
. "dh_param" allows specification of pre-generated key generation
|
||||
parameters when negotiating ephemeral DHE ciphers in stream servers.
|
||||
. "ecdh_curve" allows stream servers to specify which curve to use when
|
||||
negotiating ephemeral ECDHE ciphers (defaults to NIST P-256).
|
||||
. "rsa_key_size" SSL context option gives stream servers control
|
||||
over the key size (in bits) used when negotiating RSA ciphers.
|
||||
. "capture_session_meta" if specified stores an array of data describing
|
||||
the TLS session's protocol/cipher in the "session_meta" SSL context key.
|
||||
|
||||
- Added automatic mitigation against client-initated TLS renegotiation DoS
|
||||
attacks in encrypted server streams. Renegotiation limiting may be
|
||||
customized via three new SSL context options:
|
||||
|
||||
. "reneg_limit" (number of allowed renegotiations per time window)
|
||||
. "reneg_window" (renegotiation time window in seconds)
|
||||
. "reneg_limit_callback" (optional notification callback on limiting)
|
||||
|
||||
- Encrypted TLS servers now support the server name indication (SNI) TLS
|
||||
extension via the new "SNI_server_certs" SSL context option.
|
||||
|
||||
- Added "crypto_method" SSL context option for use in encrypted streams.
|
||||
|
||||
- Added "peer_name" SSL context option to better reflect peer certificate
|
||||
name matching using SAN extension (replaces deprecated "CN_match").
|
||||
|
||||
- Added stream wrapper support when specifying "cafile" SSL context paths.
|
||||
|
||||
- Independent peer cert and peer name validation is now available via a new
|
||||
boolean "verify_peer_name" SSL context option. This option is enabled by
|
||||
default in encrypted client streams.
|
||||
|
||||
- Added protocol-specific tlsv1.0://, tlsv1.1:// and tlsv1.2:// encryption
|
||||
stream wrappers. tls:// wrapper now supports TLSv1.1 and TLSv1.2 (previously
|
||||
only supported TLSv1).
|
||||
|
||||
- Stream crypto method specification now accepts flags instead of values
|
||||
allowing support for multiple discrete protocols in a given stream.
|
||||
|
||||
- PostgreSQL database connections may now be established asynchronously using
|
||||
new constants and polling functions in ext/pgsql.
|
||||
|
||||
- Non-blocking read/write query behavior now optionally available in database
|
||||
operations using the ext/pgsql extension.
|
||||
|
||||
========================================
|
||||
3. Changes in SAPI modules
|
||||
========================================
|
||||
|
||||
- FPM
|
||||
. Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes).
|
||||
- Added phpdbg SAPI.
|
||||
(https://wiki.php.net/rfc/phpdbg)
|
||||
|
||||
- Support for FPM workers changing the apparmor profile through the pool configuration.
|
||||
(https://wiki.php.net/rfc/fpm_change_hat)
|
||||
|
||||
- Support for several XML MIME types in the built-in CLI server. For static
|
||||
files with extensions .xml, .xsl, .xsd the Content-Type header
|
||||
application/xml is now sent automatically.
|
||||
|
||||
========================================
|
||||
4. Deprecated Functionality
|
||||
========================================
|
||||
|
||||
- Incompatible context calls:
|
||||
Instance calls from an incompatible context are now deprecated and issue
|
||||
E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx
|
||||
|
||||
- The "CN_match" and "SNI_server_name" SSL context options are deprecated in
|
||||
favor of the new "peer_name" option. Name verification now checks certificate
|
||||
SAN names as well as the CN field and the specific name fields are deprecated
|
||||
to avoid confusion. Their use triggers E_DEPRECATED but continues to work as
|
||||
before. If specified, the specific values take precedence over the general
|
||||
"peer_name" value.
|
||||
|
||||
- Deprecated PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, an
|
||||
undocument constant effectively equivalent to PDO::ATTR_EMULATE_PREPARES.
|
||||
|
||||
- Deprecated INIs: Following INIs are deprecated in favour of new
|
||||
internal_encoding/input_encoding/output_encoding. Refer to "Changes to
|
||||
encodings in PHP 5.6" in "11. Other Changes" section for more details.
|
||||
|
||||
iconv.input_encoding
|
||||
iconv.output_encoding
|
||||
iconv.internal_encoding
|
||||
mbstring.http_input
|
||||
mbstring.http_output
|
||||
mbstring.internal_encoding
|
||||
|
||||
========================================
|
||||
5. Changed Functions
|
||||
========================================
|
||||
|
||||
- cURL:
|
||||
CURLOPT_SAFE_UPLOAD is now turned on by default and uploads with @file
|
||||
do not work unless it is explicitly set to false.
|
||||
|
||||
curl_setopt() now supports the following nullable settings (>= 5.5.11):
|
||||
. CURLOPT_CUSTOMREQUEST
|
||||
. CURLOPT_FTPPORT
|
||||
. CURLOPT_RANGE
|
||||
. CURLOPT_FTP_ACCOUNT
|
||||
. CURLOPT_RTSP_SESSION_ID
|
||||
. CURLOPT_KRBLEVEL
|
||||
. CURLOPT_KRB4LEVEL
|
||||
|
||||
- Strings:
|
||||
substr_compare() now allows $length to be zero.
|
||||
pack() and unpack() now support 64-bit format specifiers: q, Q, J and P.
|
||||
|
||||
- Crypt:
|
||||
crypt() will now raise an E_NOTICE error if the salt parameter is omitted.
|
||||
See: https://wiki.php.net/rfc/crypt_function_salt
|
||||
|
||||
- Mcrypt:
|
||||
The $source parameter of mcrypt_create_iv() now defaults to
|
||||
MCRYPT_DEV_URANDOM instead of MCRYPT_DEV_RANDOM.
|
||||
|
||||
- OpenSSL:
|
||||
The $crypto_type parameter is now optional in stream_socket_enable_crypto()
|
||||
if the stream's SSL context specifies the new "crypto_type" option. The
|
||||
crypto method from the context is used as a fallback if no crypto method is
|
||||
specified at call-time.
|
||||
|
||||
- Reflection:
|
||||
ReflectionClass::newInstanceWithoutConstructor previously didn't allow the
|
||||
instantiation of any internal class which used custom object storage
|
||||
(overriding the default create_object handler), this was changed to only
|
||||
reject the instantiation of such classes if the class is also marked as
|
||||
final.
|
||||
|
||||
- XMLReader:
|
||||
XMLReader::getAttributeNs and XMLReader::getAttributeNo now return NULL if
|
||||
the attribute could not be found, just like XMLReader::getAttribute.
|
||||
|
||||
- Pgsql:
|
||||
pg_insert()/pg_select()/pg_update()/pg_delete() are no longer EXPERIMENTAL.
|
||||
The following functions no longer block until query write completion if the
|
||||
socket stream underlying a database connection is set to non-blocking mode:
|
||||
. pg_send_execute()
|
||||
. pg_send_prepare()
|
||||
. pg_send_query()
|
||||
. pg_send_query_params()
|
||||
|
||||
- unserialize:
|
||||
Manipulated serialization strings for objects implementing Serializable by
|
||||
replacing "C:" with "O:" at the start will now produce an error.
|
||||
|
||||
- parse_ini_file():
|
||||
- parse_ini_string():
|
||||
Added scanner mode INI_SCANNER_TYPED to yield typed .ini values.
|
||||
For PHP >= 5.6.1
|
||||
|
||||
========================================
|
||||
6. New Functions
|
||||
========================================
|
||||
|
||||
- Datetime:
|
||||
Added DatePeriod::getStartDate(), DatePeriod::getEndDate(), DatePeriod::getDateInterval() in 5.6.5.
|
||||
|
||||
- GMP:
|
||||
Added gmp_root($a, $nth) and gmp_rootrem($a, $nth) for calculating nth roots.
|
||||
Added gmp_import($data, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) in PHP 5.6.1.
|
||||
Added gmp_export($gmpnumber, $word_size = 1, $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN) in PHP 5.6.1.
|
||||
Added gmp_random_range() and gmp_random_bits() in PHP 5.6.3.
|
||||
|
||||
- Hash
|
||||
Added hash_equals($known_string, $user_string)
|
||||
|
||||
- OpenSSL:
|
||||
Added string openssl_x509_fingerprint($x509, $type, $binary).
|
||||
Added string openssl_spki_new($private_key, $challenge, $algorithm)
|
||||
Added bool openssl_spki_verify($spkac)
|
||||
Added string openssl_spki_export($spkac)
|
||||
Added string openssl_spki_export_challenge($spkac)
|
||||
Added array openssl_get_cert_locations()
|
||||
|
||||
- LDAP:
|
||||
Added ldap_escape($value, $ignore = "", $flags = 0).
|
||||
Added ldap_modify_batch($link_identifier, $dn, $modifications) described in
|
||||
https://wiki.php.net/rfc/ldap_modify_batch.
|
||||
|
||||
- Pgsql:
|
||||
Added pg_socket($connection) to allow async connections and non-blocking IO
|
||||
Added pg_connect_poll($connection) for establishing async connections
|
||||
Added pg_consume_input($connection) for non-blocking query result consumption
|
||||
Added pg_flush($connection) for non-blocking query write completion
|
||||
|
||||
- PDO_pgsql
|
||||
Added PDO::pgsqlGetNotify($result_type = PDO::FETCH_USE_DEFAULT, $ms_timeout = 0)
|
||||
Added PDO::pgsqlGetPid()
|
||||
|
||||
- Reflection
|
||||
Added ReflectionFunction::isVariadic() and ReflectionParameter::isVariadic().
|
||||
|
||||
- SPL
|
||||
Added SplFileObject::fread($length) to complement fwrite() method (>= 5.5.11)
|
||||
|
||||
- Zip:
|
||||
Added ZipArchive::setPassword($password)
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
@@ -71,29 +324,186 @@ PHP X.Y UPGRADE NOTES
|
||||
9. Other Changes to Extensions
|
||||
========================================
|
||||
|
||||
- cURL:
|
||||
- The following constants have been removed as they are now marked "obsolete"
|
||||
in the underlying library and never had any effect to begin with:
|
||||
. CURLOPT_CLOSEPOLICY
|
||||
. CURLCLOSEPOLICY_CALLBACK
|
||||
. CURLCLOSEPOLICY_LEAST_RECENTLY_USED
|
||||
. CURLCLOSEPOLICY_LEAST_TRAFFIC
|
||||
. CURLCLOSEPOLICY_OLDEST
|
||||
. CURLCLOSEPOLICY_SLOWEST
|
||||
|
||||
- GMP:
|
||||
The GMP extension now uses objects as the underlying data structure, rather
|
||||
than resources. GMP instances now support dumping, serialization, cloning,
|
||||
casts to primitive types and have overloaded operators.
|
||||
(RFC: https://wiki.php.net/rfc/operator_overloading_gmp)
|
||||
|
||||
- OCI8:
|
||||
- Added Implicit Result Set support for Oracle Database 12c with a
|
||||
new oci_get_implicit_resultset() function.
|
||||
- Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no longer
|
||||
unnecessarily initiates an internal ROLLBACK during connection
|
||||
close.
|
||||
- Multi-row OCI_RETURN_LOB queries require fewer "round trips" to the database.
|
||||
- Added DTrace probes enabled with PHP's generic --enable-dtrace
|
||||
- The oci_internal_debug() function is now a no-op.
|
||||
- The phpinfo() output format for OCI8 has changed.
|
||||
|
||||
- OpenSSL:
|
||||
- The "SNI_enabled" SSL stream context option is now set to TRUE by default
|
||||
if supported by the underlying openssl library.
|
||||
|
||||
- PCRE:
|
||||
- The information collected by the (*MARK) backtracking control verb is now
|
||||
collected into the "MARK" index of the $matches array for preg_match(),
|
||||
preg_match_all() and preg_replace_callback().
|
||||
|
||||
- Pgsql:
|
||||
- pg_insert()/pg_select()/pg_update()/pg_delete()/pg_meta_data()/pg_convert()
|
||||
are no longer EXPERIMENTAL
|
||||
- Added PGSQL_DML_ESCAPE option for pg_insert()/pg_select()/pg_update()/pg_delete()
|
||||
that simply escapes all supplied parameters. These functions can be as fast as
|
||||
native query. Unvalidated data(Unknown data types) is passed as string.
|
||||
JSON/Array/etc are supported both PGSQL_DML_ESCAPE and pg_convert() as string.
|
||||
- pg_select() returns PostgreSQL query resource when query is executed.
|
||||
- Added extended flag parameter for pg_meta_data(). pg_meta_data() always
|
||||
returns "is enum" attribute.
|
||||
- The new pg_socket() function returns a socket stream with no behavior other
|
||||
than to allow IO-readiness polling on a DB connection socket. Calling
|
||||
stream_set_blocking() on its result enables non-blocking behavior.
|
||||
- Passing the new PGSQL_CONNECT_ASYNC flag to pg_connect() allows applications
|
||||
to poll for IO readiness via pg_connect_poll() and establish connections
|
||||
asynchronously.
|
||||
|
||||
- PDO_pgsql:
|
||||
- Added PDO::PGSQL_ATTR_DISABLE_PREPARES constant to execute the queries
|
||||
without preparing them, while still passing parameters separately from
|
||||
the command text using PQexecParams.
|
||||
- Added LISTEN/NOTIFY support via PDO::pgsqlGetNotify / PDO::pgsqlGetPid()
|
||||
as described in https://bugs.php.net/bug.php?id=42614.
|
||||
|
||||
- DOM:
|
||||
- DOMNode::textContent is now a writeable property. (>= 5.6.1)
|
||||
|
||||
========================================
|
||||
10. New Global Constants
|
||||
========================================
|
||||
|
||||
- Core
|
||||
. PHP_INT_MIN added.
|
||||
- LDAP:
|
||||
LDAP_ESCAPE_FILTER int(1)
|
||||
LDAP_ESCAPE_DN int(2)
|
||||
|
||||
- Pgsql:
|
||||
PGSQL_DML_ESCAPE int(4096)
|
||||
PGSQL_CONNECT_ASYNC
|
||||
PGSQL_CONNECTION_STARTED
|
||||
PGSQL_CONNECTION_MADE
|
||||
PGSQL_CONNECTION_AWAITING_RESPONSE
|
||||
PGSQL_CONNECTION_AUTH_OK
|
||||
PGSQL_CONNECTION_SSL_STARTUP
|
||||
PGSQL_CONNECTION_SETENV
|
||||
PGSQL_POLLING_FAILED
|
||||
PGSQL_POLLING_READING
|
||||
PGSQL_POLLING_WRITING
|
||||
PGSQL_POLLING_OK
|
||||
PGSQL_POLLING_ACTIVE
|
||||
|
||||
- OpenSSL:
|
||||
STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT int(9)
|
||||
STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT int(17)
|
||||
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT int(33)
|
||||
STREAM_CRYPTO_METHOD_ANY_CLIENT int(63)
|
||||
STREAM_CRYPTO_METHOD_TLSv1_0_SERVER int(8)
|
||||
STREAM_CRYPTO_METHOD_TLSv1_1_SERVER int(16)
|
||||
STREAM_CRYPTO_METHOD_TLSv1_2_SERVER int(32)
|
||||
STREAM_CRYPTO_METHOD_ANY_SERVER int(62)
|
||||
OPENSSL_DEFAULT_STREAM_CIPHERS string
|
||||
|
||||
========================================
|
||||
11. Changes to INI File Handling
|
||||
========================================
|
||||
|
||||
========================================
|
||||
12. Windows Support
|
||||
========================================
|
||||
- Core:
|
||||
Changed always_populate_raw_post_data to throw a deprecation warning when
|
||||
enabled and to recognize the value -1 for never populating the global
|
||||
$HTTP_RAW_POST_DATA variable, which will be default in future PHP versions.
|
||||
|
||||
- Core
|
||||
. Support for native 64 bit integers in 64 bit builds
|
||||
. Support for large files in 64 bit builds
|
||||
default_charset is set to UTF-8. It was empty previously. default_charset
|
||||
is used where it is applicable. Iconv/Mbstring/htmlentities/htmlspecialchars/
|
||||
html_entity_decode use default_charset as default encoding.
|
||||
|
||||
internal_encoding/input_encoding/output_encoding is added for encoding
|
||||
handling modules. Refer to "Changes to encodings in PHP 5.6" in "11. Other Changes"
|
||||
section for more details.
|
||||
|
||||
- cURL:
|
||||
If the new openssl.cafile ini directive is specified ext/curl will give the
|
||||
openssl path precedence over its own curl.cainfo directive.
|
||||
|
||||
- OpenSSL:
|
||||
openssl.cafile and openssl.capath ini directives have been added to allow
|
||||
global CA default specification as necessary.
|
||||
|
||||
========================================
|
||||
13. Other Changes
|
||||
12. Other Changes
|
||||
========================================
|
||||
|
||||
- Standard
|
||||
. call_user_method() and call_user_method_array() no longer exists.
|
||||
- File upload:
|
||||
Uploads equal or greater than 2GB in size are now accepted.
|
||||
|
||||
- HTTP stream wrapper:
|
||||
HTTP 1.1 requests now include a Connection: close header unless explicitly
|
||||
overridden by setting a Connection header via the header context option.
|
||||
|
||||
- PDO_pgsql
|
||||
A libpq version providing PQexecParams, PQprepare, PQescapeStringConn,
|
||||
PQescapeByteaConn is now required. According to the release notes that means
|
||||
8.0.8+ or 8.1.4+.
|
||||
|
||||
- Zip:
|
||||
New --with-libzip option allow to use system libzip. Version > 0.11 required,
|
||||
Version >= 0.11.2 recommended for all features.
|
||||
|
||||
- Changes to encodings in PHP 5.6
|
||||
The default value of default_charset is now UTF-8 when it is not
|
||||
explicitly set in php.ini
|
||||
|
||||
The following php.ini parameters were added:
|
||||
internal_encoding
|
||||
input_encoding
|
||||
output_encoding
|
||||
|
||||
The values of the following php.ini parameters have become empty in
|
||||
PHP 5.6 (previously they were all ISO-8859-1)
|
||||
|
||||
iconv.input_encoding
|
||||
iconv.output_encoding
|
||||
iconv.internal_encoding
|
||||
|
||||
Changes were made to character set handling in:
|
||||
- the iconv and mbstring extensions,
|
||||
- and htmlentities(), htmlspecialchars(), html_entity_decode() functions
|
||||
|
||||
The precedence for these is now:
|
||||
|
||||
default_charset < internal/input/output_encoding < (mbstring.* || iconv.*) < function parameter
|
||||
|
||||
For example, the easiest way to use the UTF-8 encoding is to set
|
||||
default_charset=UTF-8 and leave the following php.ini parameters
|
||||
|
||||
empty:
|
||||
|
||||
iconv.input_encoding
|
||||
iconv.output_encoding
|
||||
iconv.internal_encoding
|
||||
mbstring.http_input
|
||||
mbstring.http_output
|
||||
mbstring.internal_encoding
|
||||
internal_encoding
|
||||
input_encoding
|
||||
output_encoding
|
||||
|
||||
The mb_regex_encoding() default setting is changed from EUC-JP to UTF-8.
|
||||
|
||||
+181
-71
@@ -1,18 +1,19 @@
|
||||
$Id$
|
||||
|
||||
UPGRADE NOTES - PHP X.Y
|
||||
PHP 5.6 INTERNALS UPGRADE NOTES
|
||||
|
||||
1. Internal API changes
|
||||
a. Addition of do_operation and compare object handlers
|
||||
b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros
|
||||
c. POST data handling
|
||||
d. Arginfo changes
|
||||
e. New data types
|
||||
f. zend_parse_parameters() specs
|
||||
g. sprintf() formats
|
||||
h. HashTable API
|
||||
i. New portable macros for large file support
|
||||
j. New portable macros for integers
|
||||
e. tsrm_virtual_cwd.h moved to zend_virtual_cwd.h
|
||||
f. empty strings are interned
|
||||
g. Additional str_* APIs
|
||||
h. Addition of zend_hash_reindex
|
||||
i. Addition of zend_hash_splice
|
||||
j. Unserialization of manipulated object strings
|
||||
k. Removal of IS_CONSTANT_ARRAY and IS_CONSTANT_INDEX hack
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
@@ -23,93 +24,202 @@ UPGRADE NOTES - PHP X.Y
|
||||
1. Internal API changes
|
||||
========================
|
||||
|
||||
a. zend_set_memory_limit() now takes the TSRMLS_CC macro as its last argument
|
||||
e. New data types
|
||||
a. Addition of do_operation and compare object handlers
|
||||
|
||||
String
|
||||
Two new object handlers have been added:
|
||||
|
||||
Besides the old way of accepting the strings with 's', the new 'S' ZPP spec
|
||||
was introduced. It expects an argument of the type zend_string *. String lengths
|
||||
in it do no more depend on the firm 'int' datatype. The replacement
|
||||
is a platform dependent size_t datatype called php_size_t.
|
||||
do_operation:
|
||||
typedef int (*zend_object_do_operation_t)(
|
||||
zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC
|
||||
);
|
||||
|
||||
String length is defined as zend_size_t inside Zend and aliased as php_size_t
|
||||
anywhere else. The inclusion of php.h is necessary.
|
||||
compare:
|
||||
typedef int (*zend_object_compare_zvals_t)(
|
||||
zval *result, zval *op1, zval *op2 TSRMLS_DC
|
||||
);
|
||||
|
||||
Integer types
|
||||
The first handler is used to overload arithmetic operations. The first
|
||||
argument specifies the opcode of the operator, result is the target zval,
|
||||
op1 the first operand and op2 the second operand. For unary operations
|
||||
op2 is NULL. If the handler returns FAILURE PHP falls back to the default
|
||||
behavior for the operation.
|
||||
|
||||
Integers do no more depend on the firm 'long' type. Instead a platform
|
||||
dependent integer type is used. That datatype is defined dynamically to
|
||||
guarantee the consistent 64 bit support. The zval field representing user
|
||||
land integer it bound to php_int_t.
|
||||
The second handler is used to perform comparison operations with
|
||||
non-objects. The value written into result must be an IS_LONG with value
|
||||
-1 (smaller), 0 (equal) or 1 (greater). The return value is a SUCCESS/FAILURE
|
||||
return code. The difference between this handler and compare_objects is
|
||||
that it will be triggered for comparisons with non-objects and objects of
|
||||
different types. It takes precedence over compare_objects.
|
||||
|
||||
Signed integer is defined as zend_int_t, unsigned integer as zend_uint_t
|
||||
inside Zend. Both are aliased as php_int_t and php_uint_t anywhere else,
|
||||
respectively. The inclusion of php.h is necessary.
|
||||
Further docs in the RFC: https://wiki.php.net/rfc/operator_overloading_gmp
|
||||
|
||||
Other datatypes
|
||||
b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros
|
||||
|
||||
zend_off_t - portable off_t analogue
|
||||
zend_stat_t - portable 'struct stat' analogue
|
||||
The return_value_ptr argument to internal functions is now always set.
|
||||
Previously it was only available for functions returning by-reference.
|
||||
return_value_ptr can now be used to return zvals without copying them.
|
||||
For this purpose two new macros are provided:
|
||||
|
||||
These datatypes are declared to be portable across platforms. Thus, direct
|
||||
usage of the functions like fseek, stat, etc. as well as direct usage of
|
||||
off_t and struct stat is strongly not recommended. Instead the portable
|
||||
macros should be used.
|
||||
RETVAL_ZVAL_FAST(zv); /* analog to RETVAL_ZVAL(zv, 1, 0) */
|
||||
RETURN_ZVAL_FAST(zv); /* analog to RETURN_ZVAL(zv, 1, 0) */
|
||||
|
||||
zend_fseek - portable fseek equivalent
|
||||
zend_ftell - portable ftell equivalent
|
||||
zend_lseek - portable lseek equivalent
|
||||
zend_fstat - portable fstat equivalent
|
||||
zend_stat - portable stat equivalent
|
||||
The macros behave similarly to the non-FAST variants with copy=1 and
|
||||
dtor=0, but will try to return the zval without making a copy by utilizing
|
||||
return_value_ptr.
|
||||
|
||||
c. POST data handling
|
||||
|
||||
The sapi_request_info's members post_data, post_data_len and raw_post_data as
|
||||
well as raw_post_data_len have been replaced with a temp PHP stream
|
||||
request_body.
|
||||
|
||||
The recommended way to access raw POST data is to open and use a php://input
|
||||
stream wrapper. It is safe to be used concurrently and more than once.
|
||||
|
||||
f. zend_parse_parameters() specs
|
||||
d. Arginfo changes
|
||||
|
||||
The new spec 'S' introduced, which expects an argument of type zend_string *.
|
||||
The new specs 'i' and 'I' introduced, which expect an argument of type php_int_t.
|
||||
The pass_rest_by_reference argument of the ZEND_BEGIN_ARG_INFO and
|
||||
ZEND_BEGIN_ARG_INFO_EX() is no longer used. The value passed to it is ignored.
|
||||
|
||||
g. sprintf() formats
|
||||
Instead a variadic argument is created using ZEND_ARG_VARIADIC_INFO():
|
||||
|
||||
New printf modifier 'p' was implemented to platform independently output php_int_t,
|
||||
php_uint_t and php_size_t datatypes. That modifier can be used with'd', 'u', 'x' and 'o'
|
||||
printf format specs with spprintf, snprintf and the wrapping printf implementations.
|
||||
%pu is sufficient for both php_uint_t and php_size_t. the code using %p spec to output
|
||||
pointer address might need to be enclosed into #ifdef when it unlickily followed by 'd',
|
||||
'u', 'x' or 'o'.
|
||||
ZEND_ARG_VARIADIC_INFO(0, name) /* pass rest by value */
|
||||
ZEND_ARG_VARIADIC_INFO(1, name) /* pass rest by reference */
|
||||
ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, name)
|
||||
/* pass rest by prefer-ref */
|
||||
|
||||
The only exceptions are the snprintf and zend_sprintf functions yet, because in some cases
|
||||
they can use the implemenations available on the system, not the PHP one. Fro snprintf the
|
||||
the macros ZEND_INT_FMT ZEND_UINT_FMT should be used.
|
||||
ZEND_ARG_VARIADIC_INFO() should only be used for the last argument.
|
||||
|
||||
h. HashTable API
|
||||
The following changes were applied to the zend_arg_info struct:
|
||||
|
||||
Datatype for array indexes was changed to php_uint_t, for string keys to zend_string *.
|
||||
typedef struct _zend_arg_info {
|
||||
const char *class_name;
|
||||
zend_uint class_name_len;
|
||||
zend_uchar type_hint;
|
||||
+ zend_uchar pass_by_reference;
|
||||
zend_bool allow_null;
|
||||
- zend_bool pass_by_reference;
|
||||
+ zend_bool is_variadic;
|
||||
} zend_arg_info;
|
||||
|
||||
i. New portable macros for large file support
|
||||
The following changes were applied to the zend_internal_function_info struct:
|
||||
|
||||
Function(s) Alias Comment
|
||||
stat, _stat64 zend_stat for use with zend_stat_t
|
||||
fstat, _fstat64 zend_fstat for use with zend_stat_t
|
||||
lseek, _lseeki64 zend_lseek for use with zend_off_t
|
||||
ftell, _ftelli64 zend_ftell for use with zend_off_t
|
||||
fseek, _fseeki64 zend_fseek for use with zend_off_t
|
||||
typedef struct _zend_internal_function_info {
|
||||
zend_uint required_num_args;
|
||||
zend_uchar _type_hint;
|
||||
zend_bool return_reference;
|
||||
- zend_bool pass_rest_by_reference;
|
||||
+ zend_bool _allow_null;
|
||||
+ zend_bool _is_variadic;
|
||||
} zend_internal_function_info;
|
||||
|
||||
j. New portable macros for integers
|
||||
The CHECK_ARG_SEND_TYPE(), ARG_MUST_BE_SENT_BY_REF(),
|
||||
ARG_SHOULD_BE_SENT_BY_REF() and ARG_MAY_BE_SENT_BY_REF() macros now assume
|
||||
that the argument passed to them is a zend_function* and that it is non-NULL.
|
||||
|
||||
Function(s) Alias Comment
|
||||
snprintf with "%ld" or "%lld", _ltoa_s, _i64toa_s ZEND_ITOA for use with zend_int_t
|
||||
atol, atoll, _atoi64 ZEND_ATOI for use with zend_int_t
|
||||
strtol, strtoll, _strtoi64 ZEND_STRTOI for use with zend_int_t
|
||||
strtoul, strtoull, _strtoui64 ZEND_STRTOUI for use with zend_int_t
|
||||
abs, llabs, _abs64 ZEND_ABS for use with zend_int_t
|
||||
- ZEND_INT_MAX Aliased with PHP_INT_MAX in php.h, replaces LONG_MAX where appropriate
|
||||
- ZEND_INT_MIN Aliased with PHP_INT_MIN in php.h, replaces LONG_MIN where appropriate
|
||||
- ZEND_UINT_MAX ULONG_MAX
|
||||
- SIZEOF_ZEND_INT Replaces SIZEOF_ZEND_LONG where appropriate
|
||||
- ZEND_SIZE_MAX Max value of zend_size_t
|
||||
e. tsrm_virtual_cwd.h moved to zend_virtual_cwd.h
|
||||
|
||||
Memory allocation is now managed by emalloc/efree instead of malloc/free.
|
||||
|
||||
f. empty strings are interned
|
||||
|
||||
String created using STR_EMPTY_ALLOC() are now interned.
|
||||
convert_to_string use STR_EMPTY_ALLOC() for zval when IS_NULL.
|
||||
str_efree() shoud be preferred as efree() on such strings can cause memory
|
||||
corruption.
|
||||
|
||||
g. Additional str_* APIs
|
||||
|
||||
In addition to the previously existing str_free() and str_efree() macros, the
|
||||
following macros have been introduced to simplify dealing with potentially
|
||||
interned strings:
|
||||
|
||||
str_efree_rel(str) - efree_rel() if not interned
|
||||
str_erealloc(str, new_len) - erealloc() or emalloc+memcpy if interned
|
||||
str_estrndup(str, len) - estrndup() if not interned
|
||||
str_strndup(str, len) - zend_strndup() if not interned
|
||||
str_hash(str, len) - INTERNED_HASH(str) if interned,
|
||||
zend_hash_func(str, len+1) otherwise
|
||||
|
||||
h. Addition of zend_hash_reindex
|
||||
|
||||
A zend_hash_reindex() function with the following prototype has been added:
|
||||
|
||||
void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
|
||||
|
||||
If only_integer_keys==0, this function will change all keys to be continuous,
|
||||
zero-based integers in hash order. If only_integer_keys==1 the same will be
|
||||
done only for keys that were already integers previously, while leaving
|
||||
string keys alone.
|
||||
|
||||
i. Addition of zend_hash_splice
|
||||
|
||||
A zend_hash_splice() macro with the following prototype has been added:
|
||||
|
||||
void zend_hash_splice(
|
||||
HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor,
|
||||
uint offset, uint length,
|
||||
void **list, uint list_count, HashTable *removed
|
||||
);
|
||||
|
||||
This function performs an in-place splice operation on a hashtable:
|
||||
|
||||
The elements between offset and offset+length are removed and the elements in
|
||||
list[list_count] are inserted in their place. The removed elements can be
|
||||
optionally collected into a hashtable.
|
||||
|
||||
This operation reindexes the hashtable, i.e. integer keys will be zero-based
|
||||
and sequential, while string keys stay intact. The same applies to the
|
||||
elements inserted into the removed HT.
|
||||
|
||||
As a side-effect of this addition the signature of the php_splice() function
|
||||
changed:
|
||||
|
||||
void php_splice(
|
||||
HashTable *ht, zend_uint offset, zend_uint length,
|
||||
zval ***list, zend_uint list_count, HashTable *removed TSRMLS_DC
|
||||
)
|
||||
|
||||
This function now directly forwards to zend_hash_splice(), resets the
|
||||
IAP of ht (for compatibility with the previous implementation) and resets
|
||||
CVs if the passed hashtable is the global symbol table.
|
||||
|
||||
j. Unserialization of manipulated object strings
|
||||
|
||||
Strings requiring unserialization of objects are now explicitly checked
|
||||
whether the object they contain implements the Serializable interface.
|
||||
This solves the situation where manipulated strings could be passed for
|
||||
objects using Serializable to disallow serialization. An object
|
||||
implementing Serializable will always start with "C:" in the serialized
|
||||
string, all other objects are represented with starting "O:". Objects
|
||||
implementing Serializable to disable serialization using
|
||||
zend_class_unserialize_deny and zend_class_serialize_deny, when
|
||||
instantiated from the serializer with a manipulated "O:" string at the
|
||||
start, will most likely be defectively initialized. This is now
|
||||
fixed at the appropriate place by checking for the presence of the
|
||||
serialize callback in the class entry.
|
||||
|
||||
k. Removal of IS_CONSTANT_ARRAY and IS_CONSTANT_INDEX hack
|
||||
|
||||
These two #defines disappeared. Instead we have now IS_CONSTANT_AST which
|
||||
covers also the functionality IS_CONSTANT_ARRAY bid and furthermore the
|
||||
hack for marking zvals as constant index with IS_CONSTANT_INDEX is now
|
||||
superfluous and so removed.
|
||||
Please note that IS_CONSTANT_AST now has the same value than
|
||||
IS_CONSTANT_ARRAY had.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
||||
|
||||
a. Unix build system changes
|
||||
- The bison version check is now a blacklist instead of a whitelist.
|
||||
- The bison binary can be specified through the YACC environment/configure
|
||||
variable. Previously `bison` was assumed to be in $PATH.
|
||||
|
||||
b. Windows build system changes
|
||||
- The configure option --enable-static-analyze isn't available anymore.
|
||||
The new option was introduced --with-analyzer.
|
||||
- It is possible to disable PGO for single extensions, to do that
|
||||
define a global variable PHP_MYMODULE_PGO evaluating to false
|
||||
inside config.w32
|
||||
+1
-1
@@ -44,7 +44,7 @@ int(0)
|
||||
int(2)
|
||||
int(0)
|
||||
|
||||
Warning: Missing argument 2 for test3()%s
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
int(1)
|
||||
int(2)
|
||||
int(1)
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ bool(false)
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Missing argument 2 for test3()%s
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
int(1)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ array(2) {
|
||||
array(0) {
|
||||
}
|
||||
|
||||
Warning: Missing argument 2 for test3()%s
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Identical comparison of array with references
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$foo = 42;
|
||||
$array1 = [&$foo];
|
||||
$array2 = [$foo];
|
||||
var_dump($array1 === $array2);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -6,4 +6,4 @@ Bug #24773 (unset() of integers treated as arrays causes a crash)
|
||||
unset($array["lvl1"]["lvl2"]["b"]);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use string offset as an array in %s on line %d
|
||||
Fatal error: Cannot unset string offsets in %s on line %d
|
||||
@@ -42,6 +42,7 @@ $page["name"] = A::A_ftk();
|
||||
Non-static method A::A_ftk() should not be called statically
|
||||
1 %sbug38047.php:13 get_error_context()
|
||||
2 %sbug38047.php:36 kalus_error_handler()
|
||||
3 %sbug38047.php:36 A_ftk()
|
||||
|
||||
Missing argument 1 for A::A_ftk(), called in %sbug38047.php on line 36 and defined
|
||||
1 %sbug38047.php:13 get_error_context()
|
||||
|
||||
@@ -25,7 +25,7 @@ try {
|
||||
--EXPECTF--
|
||||
1. exception 'Exception' with message 'aaa' in %sbug52361.php:5
|
||||
Stack trace:
|
||||
#0 %sbug52361.php(13): aaa->__destruct()
|
||||
#0 %sbug52361.php(16): aaa->__destruct()
|
||||
#1 %sbug52361.php(16): bbb()
|
||||
#2 {main}
|
||||
2. exception 'Exception' with message 'bbb' in %sbug52361.php:13
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Bug #54013 (ReflectionParam for duplicate parameter contains garbage) (PHP7)
|
||||
Bug #54013 (ReflectionParam for duplicate parameter contains garbage)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -21,4 +21,11 @@ var_dump($params[0], $params[1]);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Redefinition of parameter $aaaaaaaa in %sbug54013.php on line 5
|
||||
object(ReflectionParameter)#%d (1) {
|
||||
["name"]=>
|
||||
string(8) "aaaaaaaa"
|
||||
}
|
||||
object(ReflectionParameter)#%d (1) {
|
||||
["name"]=>
|
||||
string(8) "aaaaaaaa"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Bug #60825 (Segfault when running symfony 2 tests) (PHP7)
|
||||
Bug #60825 (Segfault when running symfony 2 tests)
|
||||
--DESCRIPTION--
|
||||
run this with valgrind
|
||||
--FILE--
|
||||
@@ -13,10 +13,7 @@ class test {
|
||||
}
|
||||
$a = new test;
|
||||
require_once $a;
|
||||
debug_zval_dump($a, test::$x);
|
||||
debug_zval_dump(test::$x);
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(test)#%d (0) refcount(%d){
|
||||
}
|
||||
object(test)#%d (0) refcount(%d){
|
||||
}
|
||||
string(%d) "%sbug60825.php" refcount(2)
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Bug #64515 (Memoryleak when using the same variablename 2times in function declaration) (PHP7)
|
||||
Bug #64515 (Memoryleak when using the same variablename 2times in function declaration)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($unused = null, $unused = null, $arg = array()) {
|
||||
@@ -8,5 +8,5 @@ function foo($unused = null, $unused = null, $arg = array()) {
|
||||
foo();
|
||||
echo "okey";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Redefinition of parameter $unused in %sbug64515.php on line 2
|
||||
--EXPECT--
|
||||
okey
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #64896 (Segfault with gc_collect_cycles using unserialize on certain objects)
|
||||
--XFAIL--
|
||||
We can not fix this bug without a significant (performace slow down) change to gc
|
||||
--FILE--
|
||||
<?php
|
||||
$bar = NULL;
|
||||
@@ -36,7 +38,7 @@ object(bad)#4 (1) {
|
||||
*/
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(bad)#%d (1) {
|
||||
bject(bad)#%d (1) {
|
||||
["_private":"bad":private]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #65419 (Inside trait, self::class != __CLASS__)
|
||||
--FILE--
|
||||
<?php
|
||||
trait abc
|
||||
{
|
||||
static function def()
|
||||
{
|
||||
echo self::class, "\n";
|
||||
echo __CLASS__, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
class ghi
|
||||
{
|
||||
use abc;
|
||||
}
|
||||
|
||||
ghi::def();
|
||||
?>
|
||||
--EXPECTF--
|
||||
ghi
|
||||
ghi
|
||||
@@ -11,8 +11,7 @@ class Test
|
||||
protected static $array = [
|
||||
self::FIRST => 'first',
|
||||
'second',
|
||||
'third',
|
||||
4,
|
||||
'third'
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
@@ -23,13 +22,9 @@ class Test
|
||||
|
||||
$test = new Test();
|
||||
?>
|
||||
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
array (
|
||||
1 => 'first',
|
||||
2 => 'second',
|
||||
3 => 'third',
|
||||
4 => 4,
|
||||
)
|
||||
===DONE===
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #67111: Memory leak when using "continue 2" inside two foreach loops
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$array1 = [1, 2, 3];
|
||||
$array2 = [1, 2, 3];
|
||||
|
||||
foreach ($array1 as $x) {
|
||||
foreach ($array2 as $y) {
|
||||
echo "$x.$y\n";
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
1.1
|
||||
2.1
|
||||
3.1
|
||||
@@ -19,6 +19,6 @@ $b = new b();
|
||||
$b->test();
|
||||
|
||||
--EXPECTF--
|
||||
Strict Standards: Declaration of b::test() should be compatible with a::test($arg = c::TESTCONSTANT) in %s/bug67436/b.php on line %d
|
||||
Strict Standards: Declaration of b::test() should be compatible with a::test($arg = c::TESTCONSTANT) in %s%ebug67436%eb.php on line %d
|
||||
b::test()
|
||||
a::test(c::TESTCONSTANT)
|
||||
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
Bug #67633: A foreach on an array returned from a function not doing copy-on-write
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function id($x) {
|
||||
return $x;
|
||||
}
|
||||
|
||||
function &ref_id(&$x) {
|
||||
return $x;
|
||||
}
|
||||
|
||||
$c = 'c';
|
||||
$array = ['a', 'b', $c];
|
||||
|
||||
foreach(id($array) as &$v) {
|
||||
$v .= 'q';
|
||||
}
|
||||
var_dump($array);
|
||||
|
||||
foreach(ref_id($array) as &$v) {
|
||||
$v .= 'q';
|
||||
}
|
||||
var_dump($array);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "b"
|
||||
[2]=>
|
||||
string(1) "c"
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(2) "aq"
|
||||
[1]=>
|
||||
string(2) "bq"
|
||||
[2]=>
|
||||
&string(2) "cq"
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
--TEST--
|
||||
Bug #67856 (Leak when using array_reduce with by-ref function)
|
||||
--FILE--
|
||||
<?php
|
||||
$array = [1, 2, 3];
|
||||
var_dump(array_reduce($array, function(&$a, &$b) {
|
||||
return $a + $b;
|
||||
}, 0));
|
||||
?>
|
||||
--EXPECT--
|
||||
int(6)
|
||||
@@ -1,19 +0,0 @@
|
||||
--TEST--
|
||||
Bug #67858: Leak when $php_errormsg already set
|
||||
--INI--
|
||||
track_errors=1
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function f() {
|
||||
$php_errormsg = [1, 2, 3];
|
||||
echo $var;
|
||||
var_dump($php_errormsg);
|
||||
}
|
||||
f();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Undefined variable: var in %s on line %d
|
||||
string(23) "Undefined variable: var"
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
Bug #67874 Crash in array_map()
|
||||
--FILE--
|
||||
<?php
|
||||
$a = array(1,2,3);
|
||||
$data = array($a);
|
||||
$data = array_map('current', $data);
|
||||
var_dump($data);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Bug #67938: Segfault when extending interface method with variadic
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface TestInterface {
|
||||
public function foo();
|
||||
public function bar(array $bar);
|
||||
}
|
||||
|
||||
class Test implements TestInterface {
|
||||
public function foo(...$args) {
|
||||
echo __METHOD__, "\n";
|
||||
}
|
||||
public function bar(array $bar, ...$args) {
|
||||
echo __METHOD__, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Test;
|
||||
$obj->foo();
|
||||
$obj->bar([]);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Test::foo
|
||||
Test::bar
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #67985 - Last used array index not copied to new array at assignment
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = ['zero', 'one', 'two'];
|
||||
unset($a[2]);
|
||||
$b = $a;
|
||||
$a[] = 'three';
|
||||
$b[] = 'three';
|
||||
|
||||
var_dump($a === $b);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #68118: $a->foo .= 'test'; can leave $a->foo undefined
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function() {
|
||||
$obj = new stdClass;
|
||||
$obj->test = 'meow';
|
||||
return true;
|
||||
});
|
||||
|
||||
$a = new stdClass;
|
||||
$a->undefined .= 'test';
|
||||
var_dump($a);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
object(stdClass)#2 (1) {
|
||||
["undefined"]=>
|
||||
string(4) "test"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #68370 "unset($this)" can make the program crash
|
||||
--FILE--
|
||||
<?php
|
||||
class C {
|
||||
public function test() {
|
||||
unset($this);
|
||||
return get_defined_vars();
|
||||
}
|
||||
}
|
||||
$c = new C();
|
||||
$x = $c->test();
|
||||
print_r($x);
|
||||
unset($c, $x);
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
)
|
||||
@@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
Bug #68446 (Array constant not accepted for array parameter default)
|
||||
--FILE--
|
||||
<?php
|
||||
const FOO = [1];
|
||||
const BAR = null;
|
||||
|
||||
function a(array $a = FOO) {
|
||||
var_dump($a);
|
||||
}
|
||||
|
||||
function b(array $b = BAR) {
|
||||
var_dump($b);
|
||||
}
|
||||
|
||||
b(null);
|
||||
b([]);
|
||||
b();
|
||||
a([]);
|
||||
a();
|
||||
a(null);
|
||||
?>
|
||||
--EXPECTF--
|
||||
NULL
|
||||
array(0) {
|
||||
}
|
||||
NULL
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
|
||||
Catchable fatal error: Argument 1 passed to a() must be of the type array, null given, called in %s on line %d and defined in %s on line %d
|
||||
|
||||
@@ -13,6 +13,6 @@ call_user_func(array('foo', 'teste'));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: %son-static method foo::teste() should not be called statically in %s on line %d
|
||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::teste() should not be called statically in %s on line %d
|
||||
|
||||
Fatal error: Using $this when not in object context in %s on line %d
|
||||
@@ -18,7 +18,7 @@ var_dump(call_user_func(array('foo', 'teste')));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: %son-static method foo::teste() should not be called statically in %s on line %d
|
||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::teste() should not be called statically in %s on line %d
|
||||
%string|unicode%(1) "x"
|
||||
array(1) {
|
||||
[0]=>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
Conversion of a class constant to a reference after it has been cached
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
const TEST = 'TEST';
|
||||
|
||||
private $prop;
|
||||
|
||||
public function readConst() {
|
||||
$this->prop = self::TEST;
|
||||
}
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
$obj = new Test;
|
||||
$obj->readConst();
|
||||
unset($obj);
|
||||
var_dump(Test::TEST);
|
||||
}
|
||||
|
||||
doTest();
|
||||
eval('class Test2 extends Test {}');
|
||||
doTest();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "TEST"
|
||||
string(4) "TEST"
|
||||
@@ -47,10 +47,7 @@ array(1) {
|
||||
["this"]=>
|
||||
object(foo)#%d (1) {
|
||||
["a"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
*RECURSION*
|
||||
}
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ errmsg: arrays are not allowed in class constants
|
||||
class test {
|
||||
const TEST = array(1,2,3);
|
||||
}
|
||||
|
||||
var_dump(test::TEST);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
@@ -105,7 +105,7 @@ Hello, you
|
||||
Notice: Undefined variable: this in %s on line %d
|
||||
NULL
|
||||
|
||||
Strict Standards: %son-static method Hello::world() should not be called statically in %s on line %d
|
||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method Hello::world() should not be called statically in %s on line %d
|
||||
Hello, you
|
||||
|
||||
Notice: Undefined variable: this in %s on line %d
|
||||
|
||||
@@ -16,5 +16,5 @@ var_dump(gc_collect_cycles());
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2)
|
||||
int(10002)
|
||||
ok
|
||||
@@ -33,5 +33,5 @@ unset($foo);
|
||||
unset($bar);
|
||||
var_dump(gc_collect_cycles());
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
int\([23]\)
|
||||
--EXPECT--
|
||||
int(2)
|
||||
@@ -28,7 +28,6 @@ Stack trace:
|
||||
|
||||
Next exception 'Exception' with message 'foobar' in %sgc_030.php:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: foo->__destruct()
|
||||
#1 %sgc_030.php(%d): gc_collect_cycles()
|
||||
#2 {main}
|
||||
#0 %sgc_030.php(%d): foo->__destruct()
|
||||
#1 {main}
|
||||
thrown in %sgc_030.php on line %d
|
||||
@@ -11,26 +11,26 @@ $b =& $a;
|
||||
$a[0][0] = $a;
|
||||
debug_zval_dump($a);
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) refcount(%d){
|
||||
--EXPECT--
|
||||
array(1) refcount(1){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(3){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(3){
|
||||
[0]=>
|
||||
*RECURSION*
|
||||
}
|
||||
}
|
||||
}
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(1){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(3){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(1){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(3){
|
||||
[0]=>
|
||||
array(1) refcount(%d){
|
||||
array(1) refcount(1){
|
||||
[0]=>
|
||||
*RECURSION*
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ foreach ($gen as &$value) { }
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught exception 'Exception' with message 'You can only iterate a generator by-reference if it declared that it yields by-reference' in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
#0 %s(%d): unknown()
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
|
||||
@@ -56,6 +56,7 @@ Stack trace:
|
||||
|
||||
exception 'Exception' with message 'Cannot traverse an already closed generator' in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
#0 %s(%d): unknown()
|
||||
#1 {main}
|
||||
|
||||
in generator
|
||||
@@ -3,7 +3,9 @@
|
||||
--FILE--
|
||||
<?php
|
||||
const C = array();
|
||||
|
||||
var_dump(C);
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(0) {
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
--TEST--
|
||||
Inc/dec of reference object properties
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$obj = new stdClass;
|
||||
$obj->cursor = 0;
|
||||
$ref =& $obj->cursor;
|
||||
|
||||
$obj->cursor++;
|
||||
var_dump($obj->cursor);
|
||||
|
||||
$obj->cursor--;
|
||||
var_dump($obj->cursor);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(0)
|
||||
@@ -35,7 +35,7 @@ object(foo)#%d (0) {
|
||||
object(foo)#%d (0) {
|
||||
}
|
||||
|
||||
Strict Standards: %son-static method foo::test() should not be called statically in %s on line %d
|
||||
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::test() should not be called statically in %s on line %d
|
||||
|
||||
Strict Standards: Non-static method bar::show() should not be called statically in %s on line %d
|
||||
object(foo)#%d (0) {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
--TEST--
|
||||
Use power operator on reference
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = 2;
|
||||
$b = 3;
|
||||
|
||||
$ref =& $b;
|
||||
|
||||
$a **= $b;
|
||||
|
||||
var_dump($a);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(8)
|
||||
@@ -1,15 +0,0 @@
|
||||
--TEST--
|
||||
Throw reference
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$e = new Exception;
|
||||
$ref =& $e;
|
||||
throw $e;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught exception 'Exception' in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug #65576 (Constructor from trait conflicts with inherited constructor)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait T
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
echo "Trait contructor\n";
|
||||
}
|
||||
}
|
||||
|
||||
class A
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
echo "Parent constructor\n";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A
|
||||
{
|
||||
use T;
|
||||
}
|
||||
|
||||
new B();
|
||||
|
||||
--EXPECT--
|
||||
Trait contructor
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Bug #65576 (Constructor from trait conflicts with inherited constructor)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait T
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
echo "Trait contructor\n";
|
||||
}
|
||||
}
|
||||
|
||||
class A
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
echo "Parent constructor\n";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A
|
||||
{
|
||||
use T;
|
||||
}
|
||||
|
||||
new B();
|
||||
|
||||
--EXPECT--
|
||||
Parent constructor
|
||||
Trait contructor
|
||||
|
||||
+297
-277
@@ -46,22 +46,21 @@
|
||||
|
||||
/* true multithread-shared globals */
|
||||
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
|
||||
ZEND_API size_t (*zend_printf)(const char *format, ...);
|
||||
ZEND_API int (*zend_printf)(const char *format, ...);
|
||||
ZEND_API zend_write_func_t zend_write;
|
||||
ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC);
|
||||
ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
|
||||
ZEND_API void (*zend_block_interruptions)(void);
|
||||
ZEND_API void (*zend_unblock_interruptions)(void);
|
||||
ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC);
|
||||
ZEND_API void (*zend_ticks_function)(int ticks);
|
||||
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
size_t (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
|
||||
int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
|
||||
ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
|
||||
|
||||
void (*zend_on_timeout)(int seconds TSRMLS_DC);
|
||||
|
||||
static void (*zend_message_dispatcher_p)(zend_long message, const void *data TSRMLS_DC);
|
||||
static void (*zend_message_dispatcher_p)(long message, const void *data TSRMLS_DC);
|
||||
static int (*zend_get_configuration_directive_p)(const char *name, uint name_length, zval *contents);
|
||||
|
||||
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
|
||||
@@ -124,6 +123,8 @@ static HashTable *global_persistent_list = NULL;
|
||||
|
||||
ZEND_API zend_utility_values zend_uv;
|
||||
|
||||
ZEND_API zval zval_used_for_init; /* True global variable */
|
||||
|
||||
/* version information */
|
||||
static char *zend_version_info;
|
||||
static uint zend_version_info_length;
|
||||
@@ -132,9 +133,11 @@ static uint zend_version_info_length;
|
||||
|
||||
static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *tmp;
|
||||
zend_string *string_key;
|
||||
zend_ulong num_key;
|
||||
zval **tmp;
|
||||
char *string_key;
|
||||
HashPosition iterator;
|
||||
ulong num_key;
|
||||
uint str_len;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++) {
|
||||
@@ -142,45 +145,46 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
|
||||
}
|
||||
ZEND_PUTS_EX("(\n");
|
||||
indent += PRINT_ZVAL_INDENT;
|
||||
ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) {
|
||||
if (Z_TYPE_P(tmp) == IS_INDIRECT) {
|
||||
tmp = Z_INDIRECT_P(tmp);
|
||||
if (Z_TYPE_P(tmp) == IS_UNDEF) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
zend_hash_internal_pointer_reset_ex(ht, &iterator);
|
||||
while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
|
||||
for (i = 0; i < indent; i++) {
|
||||
ZEND_PUTS_EX(" ");
|
||||
}
|
||||
ZEND_PUTS_EX("[");
|
||||
if (string_key) {
|
||||
if (is_object) {
|
||||
const char *prop_name, *class_name;
|
||||
int prop_len;
|
||||
int mangled = zend_unmangle_property_name_ex(string_key->val, string_key->len, &class_name, &prop_name, &prop_len);
|
||||
switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
|
||||
case HASH_KEY_IS_STRING:
|
||||
if (is_object) {
|
||||
const char *prop_name, *class_name;
|
||||
int prop_len;
|
||||
int mangled = zend_unmangle_property_name_ex(string_key, str_len - 1, &class_name, &prop_name, &prop_len);
|
||||
|
||||
ZEND_WRITE_EX(prop_name, prop_len);
|
||||
if (class_name && mangled == SUCCESS) {
|
||||
if (class_name[0]=='*') {
|
||||
ZEND_PUTS_EX(":protected");
|
||||
} else {
|
||||
ZEND_PUTS_EX(":");
|
||||
ZEND_PUTS_EX(class_name);
|
||||
ZEND_PUTS_EX(":private");
|
||||
ZEND_WRITE_EX(prop_name, prop_len);
|
||||
if (class_name && mangled == SUCCESS) {
|
||||
if (class_name[0]=='*') {
|
||||
ZEND_PUTS_EX(":protected");
|
||||
} else {
|
||||
ZEND_PUTS_EX(":");
|
||||
ZEND_PUTS_EX(class_name);
|
||||
ZEND_PUTS_EX(":private");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ZEND_WRITE_EX(string_key, str_len-1);
|
||||
}
|
||||
} else {
|
||||
ZEND_WRITE_EX(string_key->val, string_key->len);
|
||||
}
|
||||
} else {
|
||||
char key[25];
|
||||
snprintf(key, sizeof(key), ZEND_LONG_FMT, num_key);
|
||||
ZEND_PUTS_EX(key);
|
||||
break;
|
||||
case HASH_KEY_IS_LONG:
|
||||
{
|
||||
char key[25];
|
||||
snprintf(key, sizeof(key), "%ld", num_key);
|
||||
ZEND_PUTS_EX(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ZEND_PUTS_EX("] => ");
|
||||
zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
|
||||
zend_print_zval_r_ex(write_func, *tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
|
||||
ZEND_PUTS_EX("\n");
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_move_forward_ex(ht, &iterator);
|
||||
}
|
||||
indent -= PRINT_ZVAL_INDENT;
|
||||
for (i = 0; i < indent; i++) {
|
||||
ZEND_PUTS_EX(" ");
|
||||
@@ -191,124 +195,145 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
|
||||
|
||||
static void print_flat_hash(HashTable *ht TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *tmp;
|
||||
zend_string *string_key;
|
||||
zend_ulong num_key;
|
||||
zval **tmp;
|
||||
char *string_key;
|
||||
HashPosition iterator;
|
||||
ulong num_key;
|
||||
uint str_len;
|
||||
int i = 0;
|
||||
|
||||
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
|
||||
zend_hash_internal_pointer_reset_ex(ht, &iterator);
|
||||
while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
|
||||
if (i++ > 0) {
|
||||
ZEND_PUTS(",");
|
||||
}
|
||||
ZEND_PUTS("[");
|
||||
if (string_key) {
|
||||
ZEND_WRITE(string_key->val, string_key->len);
|
||||
} else {
|
||||
zend_printf(ZEND_ULONG_FMT, num_key);
|
||||
switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
|
||||
case HASH_KEY_IS_STRING:
|
||||
ZEND_PUTS(string_key);
|
||||
break;
|
||||
case HASH_KEY_IS_LONG:
|
||||
zend_printf("%ld", num_key);
|
||||
break;
|
||||
}
|
||||
ZEND_PUTS("] => ");
|
||||
zend_print_flat_zval_r(tmp TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_print_flat_zval_r(*tmp TSRMLS_CC);
|
||||
zend_hash_move_forward_ex(ht, &iterator);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC) /* {{{ */
|
||||
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy) /* {{{ */
|
||||
{
|
||||
if (Z_TYPE_P(expr) == IS_STRING) {
|
||||
return 0;
|
||||
if (Z_TYPE_P(expr)==IS_STRING) {
|
||||
*use_copy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
again:
|
||||
switch (Z_TYPE_P(expr)) {
|
||||
case IS_NULL:
|
||||
case IS_FALSE:
|
||||
ZVAL_EMPTY_STRING(expr_copy);
|
||||
break;
|
||||
case IS_TRUE:
|
||||
if (CG(one_char_string)['1']) {
|
||||
ZVAL_INTERNED_STR(expr_copy, CG(one_char_string)['1']);
|
||||
Z_STRLEN_P(expr_copy) = 0;
|
||||
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
|
||||
break;
|
||||
case IS_BOOL:
|
||||
if (Z_LVAL_P(expr)) {
|
||||
Z_STRLEN_P(expr_copy) = 1;
|
||||
Z_STRVAL_P(expr_copy) = estrndup("1", 1);
|
||||
} else {
|
||||
ZVAL_NEW_STR(expr_copy, zend_string_init("1", 1, 0));
|
||||
}
|
||||
break;
|
||||
case IS_RESOURCE: {
|
||||
char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, Z_RES_HANDLE_P(expr));
|
||||
ZVAL_NEW_STR(expr_copy, zend_string_init(buf, len, 0));
|
||||
Z_STRLEN_P(expr_copy) = 0;
|
||||
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
|
||||
}
|
||||
break;
|
||||
case IS_RESOURCE:
|
||||
Z_STRVAL_P(expr_copy) = (char *) emalloc(sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG);
|
||||
Z_STRLEN_P(expr_copy) = snprintf(Z_STRVAL_P(expr_copy), sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG, "Resource id #%ld", Z_LVAL_P(expr));
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
zend_error(E_NOTICE, "Array to string conversion");
|
||||
// TODO: use interned string ???
|
||||
ZVAL_NEW_STR(expr_copy, zend_string_init("Array", sizeof("Array") - 1, 0));
|
||||
Z_STRLEN_P(expr_copy) = sizeof("Array") - 1;
|
||||
Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
if (Z_OBJ_HANDLER_P(expr, cast_object)) {
|
||||
Z_ADDREF_P(expr);
|
||||
if (Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
|
||||
zval_ptr_dtor(expr);
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
|
||||
break;
|
||||
}
|
||||
zval_ptr_dtor(expr);
|
||||
}
|
||||
if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
|
||||
zval rv;
|
||||
zval *z = Z_OBJ_HANDLER_P(expr, get)(expr, &rv TSRMLS_CC);
|
||||
if (Z_OBJ_HANDLER_P(expr, cast_object)) {
|
||||
zval *val;
|
||||
|
||||
Z_ADDREF_P(z);
|
||||
if (Z_TYPE_P(z) != IS_OBJECT) {
|
||||
if (zend_make_printable_zval(z, expr_copy TSRMLS_CC)) {
|
||||
zval_ptr_dtor(z);
|
||||
} else {
|
||||
ZVAL_ZVAL(expr_copy, z, 0, 1);
|
||||
ALLOC_ZVAL(val);
|
||||
INIT_PZVAL_COPY(val, expr);
|
||||
zval_copy_ctor(val);
|
||||
if (Z_OBJ_HANDLER_P(expr, cast_object)(val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
|
||||
zval_ptr_dtor(&val);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
zval_ptr_dtor(&val);
|
||||
}
|
||||
zval_ptr_dtor(z);
|
||||
if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
|
||||
zval *z = Z_OBJ_HANDLER_P(expr, get)(expr TSRMLS_CC);
|
||||
|
||||
Z_ADDREF_P(z);
|
||||
if (Z_TYPE_P(z) != IS_OBJECT) {
|
||||
zend_make_printable_zval(z, expr_copy, use_copy);
|
||||
if (*use_copy) {
|
||||
zval_ptr_dtor(&z);
|
||||
} else {
|
||||
ZVAL_ZVAL(expr_copy, z, 0, 1);
|
||||
*use_copy = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
zval_ptr_dtor(&z);
|
||||
}
|
||||
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name);
|
||||
Z_STRLEN_P(expr_copy) = 0;
|
||||
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
|
||||
}
|
||||
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name->val);
|
||||
ZVAL_EMPTY_STRING(expr_copy);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
ZVAL_DUP(expr_copy, expr);
|
||||
*expr_copy = *expr;
|
||||
zval_copy_ctor(expr_copy);
|
||||
zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
expr = Z_REFVAL_P(expr);
|
||||
if (Z_TYPE_P(expr) == IS_STRING) {
|
||||
ZVAL_STR(expr_copy, zend_string_copy(Z_STR_P(expr)));
|
||||
return 1;
|
||||
}
|
||||
goto again;
|
||||
break;
|
||||
default:
|
||||
ZVAL_DUP(expr_copy, expr);
|
||||
*expr_copy = *expr;
|
||||
zval_copy_ctor(expr_copy);
|
||||
convert_to_string(expr_copy);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
Z_TYPE_P(expr_copy) = IS_STRING;
|
||||
*use_copy = 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent) /* {{{ */
|
||||
{
|
||||
return zend_print_zval_ex(zend_write, expr, indent TSRMLS_CC);
|
||||
return zend_print_zval_ex(zend_write, expr, indent);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
|
||||
{
|
||||
zend_string *str = zval_get_string(expr);
|
||||
int len = str->len;
|
||||
zval expr_copy;
|
||||
int use_copy;
|
||||
|
||||
if (len != 0) {
|
||||
write_func(str->val, len);
|
||||
zend_make_printable_zval(expr, &expr_copy, &use_copy);
|
||||
if (use_copy) {
|
||||
expr = &expr_copy;
|
||||
}
|
||||
|
||||
zend_string_release(str);
|
||||
return len;
|
||||
if (Z_STRLEN_P(expr) == 0) { /* optimize away empty strings */
|
||||
if (use_copy) {
|
||||
zval_dtor(expr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
write_func(Z_STRVAL_P(expr), Z_STRLEN_P(expr));
|
||||
if (use_copy) {
|
||||
zval_dtor(expr);
|
||||
}
|
||||
return Z_STRLEN_P(expr);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -317,51 +342,49 @@ ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) /* {{{ */
|
||||
switch (Z_TYPE_P(expr)) {
|
||||
case IS_ARRAY:
|
||||
ZEND_PUTS("Array (");
|
||||
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
|
||||
++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
|
||||
if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
|
||||
ZEND_PUTS(" *RECURSION*");
|
||||
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
||||
Z_ARRVAL_P(expr)->nApplyCount--;
|
||||
return;
|
||||
}
|
||||
print_flat_hash(Z_ARRVAL_P(expr) TSRMLS_CC);
|
||||
ZEND_PUTS(")");
|
||||
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
|
||||
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
||||
}
|
||||
Z_ARRVAL_P(expr)->nApplyCount--;
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
{
|
||||
HashTable *properties = NULL;
|
||||
zend_string *class_name = NULL;
|
||||
const char *class_name = NULL;
|
||||
zend_uint clen;
|
||||
|
||||
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
|
||||
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr), 0 TSRMLS_CC);
|
||||
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
|
||||
}
|
||||
if (class_name) {
|
||||
zend_printf("%s Object (", class_name->val);
|
||||
zend_printf("%s Object (", class_name);
|
||||
} else {
|
||||
zend_printf("%s Object (", "Unknown Class");
|
||||
}
|
||||
if (class_name) {
|
||||
zend_string_release(class_name);
|
||||
efree((char*)class_name);
|
||||
}
|
||||
if (Z_OBJ_HANDLER_P(expr, get_properties)) {
|
||||
properties = Z_OBJPROP_P(expr);
|
||||
}
|
||||
if (properties) {
|
||||
if (++properties->u.v.nApplyCount>1) {
|
||||
if (++properties->nApplyCount>1) {
|
||||
ZEND_PUTS(" *RECURSION*");
|
||||
properties->u.v.nApplyCount--;
|
||||
properties->nApplyCount--;
|
||||
return;
|
||||
}
|
||||
print_flat_hash(properties TSRMLS_CC);
|
||||
properties->u.v.nApplyCount--;
|
||||
properties->nApplyCount--;
|
||||
}
|
||||
ZEND_PUTS(")");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
zend_print_variable(expr TSRMLS_CC);
|
||||
zend_print_variable(expr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -375,57 +398,54 @@ ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC) /* {{{ */
|
||||
|
||||
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZVAL_DEREF(expr);
|
||||
switch (Z_TYPE_P(expr)) {
|
||||
case IS_ARRAY:
|
||||
ZEND_PUTS_EX("Array\n");
|
||||
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
|
||||
++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
|
||||
if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
|
||||
ZEND_PUTS_EX(" *RECURSION*");
|
||||
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
||||
Z_ARRVAL_P(expr)->nApplyCount--;
|
||||
return;
|
||||
}
|
||||
print_hash(write_func, Z_ARRVAL_P(expr), indent, 0 TSRMLS_CC);
|
||||
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
|
||||
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
||||
}
|
||||
Z_ARRVAL_P(expr)->nApplyCount--;
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
{
|
||||
HashTable *properties;
|
||||
zend_string *class_name = NULL;
|
||||
const char *class_name = NULL;
|
||||
zend_uint clen;
|
||||
int is_temp;
|
||||
|
||||
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
|
||||
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr), 0 TSRMLS_CC);
|
||||
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
|
||||
}
|
||||
if (class_name) {
|
||||
ZEND_PUTS_EX(class_name->val);
|
||||
ZEND_PUTS_EX(class_name);
|
||||
} else {
|
||||
ZEND_PUTS_EX("Unknown Class");
|
||||
}
|
||||
ZEND_PUTS_EX(" Object\n");
|
||||
if (class_name) {
|
||||
zend_string_release(class_name);
|
||||
efree((char*)class_name);
|
||||
}
|
||||
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
|
||||
break;
|
||||
}
|
||||
if (++properties->u.v.nApplyCount>1) {
|
||||
if (++properties->nApplyCount>1) {
|
||||
ZEND_PUTS_EX(" *RECURSION*");
|
||||
properties->u.v.nApplyCount--;
|
||||
properties->nApplyCount--;
|
||||
return;
|
||||
}
|
||||
print_hash(write_func, properties, indent, 1 TSRMLS_CC);
|
||||
properties->u.v.nApplyCount--;
|
||||
properties->nApplyCount--;
|
||||
if (is_temp) {
|
||||
zend_hash_destroy(properties);
|
||||
FREE_HASHTABLE(properties);
|
||||
efree(properties);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
zend_print_zval_ex(write_func, expr, indent TSRMLS_CC);
|
||||
zend_print_zval_ex(write_func, expr, indent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -443,7 +463,7 @@ static FILE *zend_fopen_wrapper(const char *filename, char **opened_path TSRMLS_
|
||||
#ifdef ZTS
|
||||
static zend_bool asp_tags_default = 0;
|
||||
static zend_bool short_tags_default = 1;
|
||||
static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
|
||||
static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
|
||||
#else
|
||||
# define asp_tags_default 0
|
||||
# define short_tags_default 1
|
||||
@@ -481,25 +501,20 @@ static void zend_init_exception_op(TSRMLS_D) /* {{{ */
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZTS
|
||||
static void function_copy_ctor(zval *zv)
|
||||
{
|
||||
zend_function *old_func = Z_FUNC_P(zv);
|
||||
Z_FUNC_P(zv) = pemalloc(sizeof(zend_internal_function), 1);
|
||||
memcpy(Z_FUNC_P(zv), old_func, sizeof(zend_internal_function));
|
||||
function_add_ref(Z_FUNC_P(zv));
|
||||
}
|
||||
|
||||
static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_function tmp_func;
|
||||
zend_class_entry *tmp_class;
|
||||
|
||||
compiler_globals->compiled_filename = NULL;
|
||||
|
||||
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
||||
zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
||||
zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
|
||||
zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
||||
zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
|
||||
|
||||
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
||||
zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
||||
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
|
||||
zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
|
||||
zend_hash_copy(compiler_globals->class_table, global_class_table, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry *));
|
||||
|
||||
zend_set_default_compile_time_values(TSRMLS_C);
|
||||
|
||||
@@ -507,7 +522,7 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS
|
||||
|
||||
compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
|
||||
zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, NULL, 1, 0);
|
||||
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, NULL /* empty element */);
|
||||
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, NULL, NULL, sizeof(zend_auto_global) /* empty element */);
|
||||
|
||||
compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
|
||||
if (compiler_globals->last_static_member) {
|
||||
@@ -537,7 +552,7 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS
|
||||
free(compiler_globals->static_members_table);
|
||||
}
|
||||
if (compiler_globals->script_encoding_list) {
|
||||
pefree((char*)compiler_globals->script_encoding_list, 1);
|
||||
pefree(compiler_globals->script_encoding_list, 1);
|
||||
}
|
||||
compiler_globals->last_static_member = 0;
|
||||
}
|
||||
@@ -550,8 +565,9 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS
|
||||
zend_init_rsrc_plist(TSRMLS_C);
|
||||
zend_init_exception_op(TSRMLS_C);
|
||||
EG(lambda_count) = 0;
|
||||
ZVAL_UNDEF(&EG(user_error_handler));
|
||||
ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
EG(user_error_handler) = NULL;
|
||||
EG(user_exception_handler) = NULL;
|
||||
EG(in_execution) = 0;
|
||||
EG(in_autoload) = NULL;
|
||||
EG(current_execute_data) = NULL;
|
||||
EG(current_module) = NULL;
|
||||
@@ -605,28 +621,16 @@ static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p
|
||||
|
||||
void zend_init_opcodes_handlers(void);
|
||||
|
||||
static void module_destructor_zval(zval *zv) /* {{{ */
|
||||
static zend_bool php_auto_globals_create_globals(const char *name, uint name_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
|
||||
zval *globals;
|
||||
|
||||
module_destructor(module);
|
||||
free(module);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void auto_global_dtor(zval *zv) /* {{{ */
|
||||
{
|
||||
free(Z_PTR_P(zv));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_bool php_auto_globals_create_globals(zend_string *name TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval globals;
|
||||
|
||||
ZVAL_ARR(&globals, &EG(symbol_table));
|
||||
ZVAL_NEW_REF(&globals, &globals);
|
||||
zend_hash_update(&EG(symbol_table).ht, name, &globals);
|
||||
ALLOC_ZVAL(globals);
|
||||
Z_SET_REFCOUNT_P(globals, 1);
|
||||
Z_SET_ISREF_P(globals);
|
||||
Z_TYPE_P(globals) = IS_ARRAY;
|
||||
Z_ARRVAL_P(globals) = &EG(symbol_table);
|
||||
zend_hash_update(&EG(symbol_table), name, name_len + 1, &globals, sizeof(zval *), NULL);
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -673,7 +677,6 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
|
||||
zend_ticks_function = utility_functions->ticks_function;
|
||||
zend_on_timeout = utility_functions->on_timeout;
|
||||
zend_vspprintf = utility_functions->vspprintf_function;
|
||||
zend_vstrpprintf = utility_functions->vstrpprintf_function;
|
||||
zend_getenv = utility_functions->getenv_function;
|
||||
zend_resolve_path = utility_functions->resolve_path_function;
|
||||
|
||||
@@ -701,14 +704,19 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
|
||||
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
||||
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
||||
|
||||
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0);
|
||||
zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);
|
||||
|
||||
zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);
|
||||
zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
|
||||
zend_init_rsrc_list_dtors();
|
||||
|
||||
/* This zval can be used to initialize allocate zval's to an uninit'ed value */
|
||||
Z_UNSET_ISREF(zval_used_for_init);
|
||||
Z_SET_REFCOUNT(zval_used_for_init, 1);
|
||||
Z_TYPE(zval_used_for_init) = IS_NULL;
|
||||
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
|
||||
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
|
||||
@@ -732,14 +740,14 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
|
||||
ini_scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
|
||||
php_scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
|
||||
zend_set_default_compile_time_values(TSRMLS_C);
|
||||
ZVAL_UNDEF(&EG(user_error_handler));
|
||||
ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
EG(user_error_handler) = NULL;
|
||||
EG(user_exception_handler) = NULL;
|
||||
#endif
|
||||
|
||||
zend_interned_strings_init(TSRMLS_C);
|
||||
zend_startup_builtin_functions(TSRMLS_C);
|
||||
zend_register_standard_constants(TSRMLS_C);
|
||||
zend_register_auto_global(zend_string_init("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals TSRMLS_CC);
|
||||
zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, 1, php_auto_globals_create_globals TSRMLS_CC);
|
||||
|
||||
#ifndef ZTS
|
||||
zend_init_rsrc_plist(TSRMLS_C);
|
||||
@@ -809,11 +817,22 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
#ifdef ZEND_SIGNALS
|
||||
zend_signal_shutdown(TSRMLS_C);
|
||||
#endif
|
||||
#ifdef ZEND_WIN32
|
||||
zend_shutdown_timeout_thread();
|
||||
#endif
|
||||
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
|
||||
|
||||
if (EG(active))
|
||||
{
|
||||
/*
|
||||
* The order of destruction is important here.
|
||||
* See bugs #65463 and 66036.
|
||||
*/
|
||||
zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
|
||||
zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) zend_cleanup_user_class_data TSRMLS_CC);
|
||||
zend_cleanup_internal_classes(TSRMLS_C);
|
||||
zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
|
||||
zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
|
||||
}
|
||||
|
||||
zend_destroy_modules();
|
||||
|
||||
virtual_cwd_deactivate(TSRMLS_C);
|
||||
@@ -872,14 +891,14 @@ ZEND_API void _zend_bailout(char *filename, uint lineno) /* {{{ */
|
||||
}
|
||||
CG(unclean_shutdown) = 1;
|
||||
CG(active_class_entry) = NULL;
|
||||
CG(in_compilation) = 0;
|
||||
CG(in_compilation) = EG(in_execution) = 0;
|
||||
EG(current_execute_data) = NULL;
|
||||
LONGJMP(*EG(bailout), FAILURE);
|
||||
}
|
||||
/* }}} */
|
||||
END_EXTERN_C()
|
||||
|
||||
void zend_append_version_info(const zend_extension *extension) /* {{{ */
|
||||
ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
|
||||
{
|
||||
char *new_info;
|
||||
uint new_info_length;
|
||||
@@ -930,7 +949,8 @@ void zend_call_destructors(TSRMLS_D) /* {{{ */
|
||||
ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
/* we're no longer executing anything */
|
||||
EG(current_execute_data) = NULL;
|
||||
EG(opline_ptr) = NULL;
|
||||
EG(active_symbol_table) = NULL;
|
||||
|
||||
zend_try {
|
||||
shutdown_scanner(TSRMLS_C);
|
||||
@@ -972,7 +992,7 @@ ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */
|
||||
/* }}} */
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_message_dispatcher(zend_long message, const void *data TSRMLS_DC) /* {{{ */
|
||||
ZEND_API void zend_message_dispatcher(long message, const void *data TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (zend_message_dispatcher_p) {
|
||||
zend_message_dispatcher_p(message, data TSRMLS_CC);
|
||||
@@ -1010,15 +1030,14 @@ ZEND_API int zend_get_configuration_directive(const char *name, uint name_length
|
||||
|
||||
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
va_list args;
|
||||
va_list usr_copy;
|
||||
zval params[5];
|
||||
zval retval;
|
||||
zval ***params;
|
||||
zval *retval;
|
||||
zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
|
||||
const char *error_filename;
|
||||
uint error_lineno = 0;
|
||||
zval orig_user_error_handler;
|
||||
uint error_lineno;
|
||||
zval *orig_user_error_handler;
|
||||
zend_bool in_compilation;
|
||||
zend_class_entry *saved_class_entry;
|
||||
zend_stack bp_stack;
|
||||
@@ -1029,14 +1048,10 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
zend_stack declare_stack;
|
||||
zend_stack list_stack;
|
||||
zend_stack context_stack;
|
||||
zend_array *symbol_table;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
/* Report about uncaught exception in case of fatal errors */
|
||||
if (EG(exception)) {
|
||||
zend_execute_data *ex;
|
||||
zend_op *opline;
|
||||
|
||||
switch (type) {
|
||||
case E_CORE_ERROR:
|
||||
case E_ERROR:
|
||||
@@ -1044,19 +1059,13 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
case E_PARSE:
|
||||
case E_COMPILE_ERROR:
|
||||
case E_USER_ERROR:
|
||||
ex = EG(current_execute_data);
|
||||
opline = NULL;
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
ex = ex->prev_execute_data;
|
||||
}
|
||||
if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
|
||||
EG(opline_before_exception)) {
|
||||
opline = EG(opline_before_exception);
|
||||
if (zend_is_executing(TSRMLS_C)) {
|
||||
error_lineno = zend_get_executed_lineno(TSRMLS_C);
|
||||
}
|
||||
zend_exception_error(EG(exception), E_WARNING TSRMLS_CC);
|
||||
EG(exception) = NULL;
|
||||
if (opline) {
|
||||
ex->opline = opline;
|
||||
if (zend_is_executing(TSRMLS_C) && EG(opline_ptr)) {
|
||||
active_opline->lineno = error_lineno;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1085,16 +1094,11 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
case E_USER_DEPRECATED:
|
||||
case E_RECOVERABLE_ERROR:
|
||||
if (zend_is_compiling(TSRMLS_C)) {
|
||||
error_filename = zend_get_compiled_filename(TSRMLS_C)->val;
|
||||
error_filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
|
||||
} else if (zend_is_executing(TSRMLS_C)) {
|
||||
error_filename = zend_get_executed_filename(TSRMLS_C);
|
||||
if (error_filename[0] == '[') { /* [no active file] */
|
||||
error_filename = NULL;
|
||||
error_lineno = 0;
|
||||
} else {
|
||||
error_lineno = zend_get_executed_lineno(TSRMLS_C);
|
||||
}
|
||||
error_lineno = zend_get_executed_lineno(TSRMLS_C);
|
||||
} else {
|
||||
error_filename = NULL;
|
||||
error_lineno = 0;
|
||||
@@ -1123,7 +1127,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
va_start(args, format);
|
||||
|
||||
/* if we don't have a user defined error handler */
|
||||
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|
||||
if (!EG(user_error_handler)
|
||||
|| !(EG(user_error_handler_error_reporting) & type)
|
||||
|| EG(error_handling) != EH_NORMAL) {
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
@@ -1139,6 +1143,12 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
break;
|
||||
default:
|
||||
/* Handle the error in user space */
|
||||
ALLOC_INIT_ZVAL(z_error_message);
|
||||
ALLOC_INIT_ZVAL(z_error_type);
|
||||
ALLOC_INIT_ZVAL(z_error_filename);
|
||||
ALLOC_INIT_ZVAL(z_error_lineno);
|
||||
ALLOC_INIT_ZVAL(z_context);
|
||||
|
||||
/* va_copy() is __va_copy() in old gcc versions.
|
||||
* According to the autoconf manual, using
|
||||
* memcpy(&dst, &src, sizeof(va_list))
|
||||
@@ -1151,35 +1161,44 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
# endif
|
||||
#endif
|
||||
va_copy(usr_copy, args);
|
||||
len = zend_vspprintf(&str, 0, format, usr_copy);
|
||||
ZVAL_NEW_STR(¶ms[1], zend_string_init(str, len, 0));
|
||||
efree(str);
|
||||
Z_STRLEN_P(z_error_message) = zend_vspprintf(&Z_STRVAL_P(z_error_message), 0, format, usr_copy);
|
||||
#ifdef va_copy
|
||||
va_end(usr_copy);
|
||||
#endif
|
||||
Z_TYPE_P(z_error_message) = IS_STRING;
|
||||
|
||||
ZVAL_LONG(¶ms[0], type);
|
||||
Z_LVAL_P(z_error_type) = type;
|
||||
Z_TYPE_P(z_error_type) = IS_LONG;
|
||||
|
||||
if (error_filename) {
|
||||
ZVAL_STRING(¶ms[2], error_filename);
|
||||
} else {
|
||||
ZVAL_NULL(¶ms[2]);
|
||||
ZVAL_STRING(z_error_filename, error_filename, 1);
|
||||
}
|
||||
|
||||
ZVAL_LONG(¶ms[3], error_lineno);
|
||||
Z_LVAL_P(z_error_lineno) = error_lineno;
|
||||
Z_TYPE_P(z_error_lineno) = IS_LONG;
|
||||
|
||||
symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
|
||||
if (!EG(active_symbol_table)) {
|
||||
zend_rebuild_symbol_table(TSRMLS_C);
|
||||
}
|
||||
|
||||
/* during shutdown the symbol table table can be still null */
|
||||
if (!symbol_table) {
|
||||
ZVAL_NULL(¶ms[4]);
|
||||
if (!EG(active_symbol_table)) {
|
||||
Z_TYPE_P(z_context) = IS_NULL;
|
||||
} else {
|
||||
ZVAL_NEW_ARR(¶ms[4]);
|
||||
zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht);
|
||||
Z_ARRVAL_P(z_context) = EG(active_symbol_table);
|
||||
Z_TYPE_P(z_context) = IS_ARRAY;
|
||||
zval_copy_ctor(z_context);
|
||||
}
|
||||
|
||||
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
|
||||
ZVAL_UNDEF(&EG(user_error_handler));
|
||||
params = (zval ***) emalloc(sizeof(zval **)*5);
|
||||
params[0] = &z_error_type;
|
||||
params[1] = &z_error_message;
|
||||
params[2] = &z_error_filename;
|
||||
params[3] = &z_error_lineno;
|
||||
params[4] = &z_context;
|
||||
|
||||
orig_user_error_handler = EG(user_error_handler);
|
||||
EG(user_error_handler) = NULL;
|
||||
|
||||
/* User error handler may include() additinal PHP files.
|
||||
* If an error was generated during comilation PHP will compile
|
||||
@@ -1201,10 +1220,9 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
CG(in_compilation) = 0;
|
||||
}
|
||||
|
||||
ZVAL_UNDEF(&retval);
|
||||
if (call_user_function_ex(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (Z_TYPE(retval) != IS_UNDEF) {
|
||||
if (Z_TYPE(retval) == IS_FALSE) {
|
||||
if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (retval) {
|
||||
if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
}
|
||||
zval_ptr_dtor(&retval);
|
||||
@@ -1227,17 +1245,19 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
CG(in_compilation) = 1;
|
||||
}
|
||||
|
||||
zval_ptr_dtor(¶ms[4]);
|
||||
zval_ptr_dtor(¶ms[3]);
|
||||
zval_ptr_dtor(¶ms[2]);
|
||||
zval_ptr_dtor(¶ms[1]);
|
||||
zval_ptr_dtor(¶ms[0]);
|
||||
|
||||
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
|
||||
ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
|
||||
} else {
|
||||
if (!EG(user_error_handler)) {
|
||||
EG(user_error_handler) = orig_user_error_handler;
|
||||
}
|
||||
else {
|
||||
zval_ptr_dtor(&orig_user_error_handler);
|
||||
}
|
||||
|
||||
efree(params);
|
||||
zval_ptr_dtor(&z_error_message);
|
||||
zval_ptr_dtor(&z_error_type);
|
||||
zval_ptr_dtor(&z_error_filename);
|
||||
zval_ptr_dtor(&z_error_lineno);
|
||||
zval_ptr_dtor(&z_context);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1246,8 +1266,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
||||
if (type == E_PARSE) {
|
||||
/* eval() errors do not affect exit_status */
|
||||
if (!(EG(current_execute_data) &&
|
||||
EG(current_execute_data)->func &&
|
||||
ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
|
||||
EG(current_execute_data)->opline &&
|
||||
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
|
||||
EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
|
||||
EG(exit_status) = 255;
|
||||
@@ -1287,13 +1306,14 @@ ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *form
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_count, ...) /* {{{ */
|
||||
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
|
||||
{
|
||||
va_list files;
|
||||
int i;
|
||||
zend_file_handle *file_handle;
|
||||
zend_op_array *op_array;
|
||||
zend_long orig_interactive = CG(interactive);
|
||||
zend_op_array *orig_op_array = EG(active_op_array);
|
||||
zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
|
||||
long orig_interactive = CG(interactive);
|
||||
|
||||
va_start(files, file_count);
|
||||
for (i = 0; i < file_count; i++) {
|
||||
@@ -1310,31 +1330,33 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
|
||||
}
|
||||
}
|
||||
|
||||
op_array = zend_compile_file(file_handle, type TSRMLS_CC);
|
||||
EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
|
||||
if (file_handle->opened_path) {
|
||||
zend_hash_str_add_empty_element(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path));
|
||||
int dummy = 1;
|
||||
zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
|
||||
}
|
||||
zend_destroy_file_handle(file_handle TSRMLS_CC);
|
||||
if (op_array) {
|
||||
zend_execute(op_array, retval TSRMLS_CC);
|
||||
if (EG(active_op_array)) {
|
||||
EG(return_value_ptr_ptr) = retval ? retval : NULL;
|
||||
zend_execute(EG(active_op_array) TSRMLS_CC);
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
if (EG(exception)) {
|
||||
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
|
||||
zval orig_user_exception_handler;
|
||||
zval params[1], retval2;
|
||||
zend_object *old_exception;
|
||||
if (EG(user_exception_handler)) {
|
||||
zval *orig_user_exception_handler;
|
||||
zval **params[1], *retval2, *old_exception;
|
||||
old_exception = EG(exception);
|
||||
EG(exception) = NULL;
|
||||
ZVAL_OBJ(¶ms[0], old_exception);
|
||||
ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
|
||||
ZVAL_UNDEF(&retval2);
|
||||
if (call_user_function_ex(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
|
||||
zval_ptr_dtor(&retval2);
|
||||
params[0] = &old_exception;
|
||||
orig_user_exception_handler = EG(user_exception_handler);
|
||||
if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (retval2 != NULL) {
|
||||
zval_ptr_dtor(&retval2);
|
||||
}
|
||||
if (EG(exception)) {
|
||||
OBJ_RELEASE(EG(exception));
|
||||
zval_ptr_dtor(&EG(exception));
|
||||
EG(exception) = NULL;
|
||||
}
|
||||
OBJ_RELEASE(old_exception);
|
||||
zval_ptr_dtor(&old_exception);
|
||||
} else {
|
||||
EG(exception) = old_exception;
|
||||
zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
|
||||
@@ -1343,15 +1365,19 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
|
||||
zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
destroy_op_array(op_array TSRMLS_CC);
|
||||
efree(op_array);
|
||||
destroy_op_array(EG(active_op_array) TSRMLS_CC);
|
||||
efree(EG(active_op_array));
|
||||
} else if (type==ZEND_REQUIRE) {
|
||||
va_end(files);
|
||||
EG(active_op_array) = orig_op_array;
|
||||
EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
|
||||
CG(interactive) = orig_interactive;
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
va_end(files);
|
||||
EG(active_op_array) = orig_op_array;
|
||||
EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
|
||||
CG(interactive) = orig_interactive;
|
||||
|
||||
return SUCCESS;
|
||||
@@ -1367,7 +1393,7 @@ ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC)
|
||||
char *compiled_string_description;
|
||||
|
||||
if (zend_is_compiling(TSRMLS_C)) {
|
||||
cur_filename = zend_get_compiled_filename(TSRMLS_C)->val;
|
||||
cur_filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
|
||||
} else if (zend_is_executing(TSRMLS_C)) {
|
||||
cur_filename = zend_get_executed_filename(TSRMLS_C);
|
||||
@@ -1386,12 +1412,6 @@ void free_estring(char **str_p) /* {{{ */
|
||||
{
|
||||
efree(*str_p);
|
||||
}
|
||||
|
||||
void free_string_zval(zval *zv) /* {{{ */
|
||||
{
|
||||
zend_string *str = Z_PTR_P(zv);
|
||||
zend_string_release(str);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
|
||||
+267
-245
@@ -22,7 +22,7 @@
|
||||
#ifndef ZEND_H
|
||||
#define ZEND_H
|
||||
|
||||
#define ZEND_VERSION "2.8.0-dev"
|
||||
#define ZEND_VERSION "2.6.0"
|
||||
|
||||
#define ZEND_ENGINE_2
|
||||
|
||||
@@ -52,20 +52,20 @@
|
||||
# define ZEND_PATHS_SEPARATOR ':'
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
/* Only use this macro if you know for sure that all of the switches values
|
||||
are covered by its case statements */
|
||||
#if ZEND_DEBUG
|
||||
# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
|
||||
#elif defined(ZEND_WIN32)
|
||||
# define EMPTY_SWITCH_DEFAULT_CASE() default: __assume(0); break;
|
||||
#define EMPTY_SWITCH_DEFAULT_CASE() \
|
||||
default: \
|
||||
__assume(0); \
|
||||
break;
|
||||
#else
|
||||
# define EMPTY_SWITCH_DEFAULT_CASE()
|
||||
#define EMPTY_SWITCH_DEFAULT_CASE()
|
||||
#endif
|
||||
|
||||
/* all HAVE_XXX test have to be after the include of zend_config above */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_UNIX_H
|
||||
# include <unix.h>
|
||||
@@ -179,14 +179,6 @@ char *alloca ();
|
||||
# define ZEND_ATTRIBUTE_DEPRECATED
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
|
||||
# define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
|
||||
# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused));
|
||||
#else
|
||||
# define ZEND_ATTRIBUTE_UNUSED
|
||||
# define ZEND_ATTRIBUTE_UNUSED_LABEL
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
|
||||
# define ZEND_FASTCALL __attribute__((fastcall))
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
@@ -260,6 +252,7 @@ char *alloca ();
|
||||
#include "zend_alloc.h"
|
||||
|
||||
#include "zend_types.h"
|
||||
#include "zend_string.h"
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
@@ -273,14 +266,14 @@ char *alloca ();
|
||||
#define LONG_MIN (- LONG_MAX - 1)
|
||||
#endif
|
||||
|
||||
#if SIZEOF_ZEND_LONG == 4
|
||||
#if SIZEOF_LONG == 4
|
||||
#define MAX_LENGTH_OF_LONG 11
|
||||
static const char long_min_digits[] = "2147483648";
|
||||
#elif SIZEOF_ZEND_LONG == 8
|
||||
#elif SIZEOF_LONG == 8
|
||||
#define MAX_LENGTH_OF_LONG 20
|
||||
static const char long_min_digits[] = "9223372036854775808";
|
||||
#else
|
||||
#error "Unknown SIZEOF_ZEND_LONG"
|
||||
#error "Unknown SIZEOF_LONG"
|
||||
#endif
|
||||
|
||||
#define MAX_LENGTH_OF_DOUBLE 32
|
||||
@@ -291,16 +284,11 @@ typedef enum {
|
||||
} ZEND_RESULT_CODE;
|
||||
|
||||
#include "zend_hash.h"
|
||||
#include "zend_ts_hash.h"
|
||||
#include "zend_llist.h"
|
||||
|
||||
#define INTERNAL_FUNCTION_PARAMETERS uint32_t param_count, zval *return_value TSRMLS_DC
|
||||
#define INTERNAL_FUNCTION_PARAM_PASSTHRU param_count, return_value TSRMLS_CC
|
||||
|
||||
#define USED_RET() \
|
||||
(!EG(current_execute_data) || \
|
||||
!EG(current_execute_data)->prev_execute_data || \
|
||||
!ZEND_USER_CODE(EG(current_execute_data)->prev_execute_data->func->common.type) || \
|
||||
!(EG(current_execute_data)->prev_execute_data->opline->result_type & EXT_TYPE_UNUSED))
|
||||
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
|
||||
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
|
||||
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
|
||||
@@ -308,38 +296,75 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
|
||||
# define zend_error_noreturn zend_error
|
||||
#endif
|
||||
|
||||
/*
|
||||
* zval
|
||||
*/
|
||||
typedef struct _zend_class_entry zend_class_entry;
|
||||
|
||||
typedef struct _zend_guard {
|
||||
zend_bool in_get;
|
||||
zend_bool in_set;
|
||||
zend_bool in_unset;
|
||||
zend_bool in_isset;
|
||||
zend_bool dummy; /* sizeof(zend_guard) must not be equal to sizeof(void*) */
|
||||
} zend_guard;
|
||||
|
||||
typedef struct _zend_object {
|
||||
zend_class_entry *ce;
|
||||
HashTable *properties;
|
||||
zval **properties_table;
|
||||
HashTable *guards; /* protects from __get/__set ... recursion */
|
||||
} zend_object;
|
||||
|
||||
#include "zend_object_handlers.h"
|
||||
#include "zend_ast.h"
|
||||
|
||||
/* overloaded elements data types */
|
||||
#define OE_IS_ARRAY (1<<0)
|
||||
#define OE_IS_OBJECT (1<<1)
|
||||
#define OE_IS_METHOD (1<<2)
|
||||
typedef union _zvalue_value {
|
||||
long lval; /* long value */
|
||||
double dval; /* double value */
|
||||
struct {
|
||||
char *val;
|
||||
int len;
|
||||
} str;
|
||||
HashTable *ht; /* hash table value */
|
||||
zend_object_value obj;
|
||||
zend_ast *ast;
|
||||
} zvalue_value;
|
||||
|
||||
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
|
||||
struct _zval_struct {
|
||||
/* Variable information */
|
||||
zvalue_value value; /* value */
|
||||
zend_uint refcount__gc;
|
||||
zend_uchar type; /* active type */
|
||||
zend_uchar is_ref__gc;
|
||||
};
|
||||
|
||||
#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))
|
||||
#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc)
|
||||
#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz))
|
||||
#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
|
||||
#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz))
|
||||
#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz))
|
||||
#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz))
|
||||
#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref)
|
||||
|
||||
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
|
||||
#define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc)
|
||||
#define Z_ADDREF_P(pz) zval_addref_p(pz)
|
||||
#define Z_DELREF_P(pz) zval_delref_p(pz)
|
||||
#define Z_ADDREF_P(pz) zval_addref_p(pz)
|
||||
#define Z_DELREF_P(pz) zval_delref_p(pz)
|
||||
#define Z_ISREF_P(pz) zval_isref_p(pz)
|
||||
#define Z_SET_ISREF_P(pz) zval_set_isref_p(pz)
|
||||
#define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz)
|
||||
#define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref)
|
||||
|
||||
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
|
||||
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
|
||||
#define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc)
|
||||
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
|
||||
#define Z_DELREF(z) Z_DELREF_P(&(z))
|
||||
|
||||
#define Z_TRY_ADDREF_P(pz) do { \
|
||||
if (Z_REFCOUNTED_P((pz))) { \
|
||||
Z_ADDREF_P((pz)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define Z_TRY_DELREF_P(pz) do { \
|
||||
if (Z_REFCOUNTED_P((pz))) { \
|
||||
Z_DELREF_P((pz)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z))
|
||||
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
|
||||
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
|
||||
#define Z_DELREF(z) Z_DELREF_P(&(z))
|
||||
#define Z_ISREF(z) Z_ISREF_P(&(z))
|
||||
#define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z))
|
||||
#define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z))
|
||||
#define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref)
|
||||
|
||||
#if ZEND_DEBUG
|
||||
#define zend_always_inline inline
|
||||
@@ -363,63 +388,43 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
|
||||
#endif /* ZEND_DEBUG */
|
||||
|
||||
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
|
||||
# define EXPECTED(condition) __builtin_expect(!(!(condition)), 1)
|
||||
# define UNEXPECTED(condition) __builtin_expect(!(!(condition)), 0)
|
||||
# define EXPECTED(condition) __builtin_expect(condition, 1)
|
||||
# define UNEXPECTED(condition) __builtin_expect(condition, 0)
|
||||
#else
|
||||
# define EXPECTED(condition) (condition)
|
||||
# define UNEXPECTED(condition) (condition)
|
||||
#endif
|
||||
|
||||
#ifndef XtOffsetOf
|
||||
# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
|
||||
# ifdef __STDC__
|
||||
# define XtOffset(p_type, field) _Offsetof(p_type, field)
|
||||
# else
|
||||
# ifdef CRAY2
|
||||
# define XtOffset(p_type, field) \
|
||||
(sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
|
||||
|
||||
# else /* !CRAY2 */
|
||||
|
||||
# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
|
||||
|
||||
# endif /* !CRAY2 */
|
||||
# endif /* __STDC__ */
|
||||
# else /* ! (CRAY || __arm) */
|
||||
|
||||
# define XtOffset(p_type, field) \
|
||||
((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
|
||||
|
||||
# endif /* !CRAY */
|
||||
|
||||
# ifdef offsetof
|
||||
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
|
||||
# else
|
||||
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "zend_string.h"
|
||||
|
||||
static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
|
||||
return GC_REFCOUNT(Z_COUNTED_P(pz));
|
||||
static zend_always_inline zend_uint zval_refcount_p(zval* pz) {
|
||||
return pz->refcount__gc;
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t zval_set_refcount_p(zval* pz, uint32_t rc) {
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
|
||||
return GC_REFCOUNT(Z_COUNTED_P(pz)) = rc;
|
||||
static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) {
|
||||
return pz->refcount__gc = rc;
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t zval_addref_p(zval* pz) {
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
|
||||
return ++GC_REFCOUNT(Z_COUNTED_P(pz));
|
||||
static zend_always_inline zend_uint zval_addref_p(zval* pz) {
|
||||
return ++pz->refcount__gc;
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t zval_delref_p(zval* pz) {
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
|
||||
return --GC_REFCOUNT(Z_COUNTED_P(pz));
|
||||
static zend_always_inline zend_uint zval_delref_p(zval* pz) {
|
||||
return --pz->refcount__gc;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool zval_isref_p(zval* pz) {
|
||||
return pz->is_ref__gc;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool zval_set_isref_p(zval* pz) {
|
||||
return pz->is_ref__gc = 1;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) {
|
||||
return pz->is_ref__gc = 0;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) {
|
||||
return pz->is_ref__gc = isref;
|
||||
}
|
||||
|
||||
/* excpt.h on Digital Unix 4.0 defines function_table */
|
||||
@@ -437,18 +442,20 @@ typedef struct _zend_serialize_data zend_serialize_data;
|
||||
typedef struct _zend_unserialize_data zend_unserialize_data;
|
||||
|
||||
struct _zend_trait_method_reference {
|
||||
zend_string *method_name;
|
||||
const char* method_name;
|
||||
unsigned int mname_len;
|
||||
|
||||
zend_class_entry *ce;
|
||||
zend_string *class_name;
|
||||
|
||||
const char* class_name;
|
||||
unsigned int cname_len;
|
||||
};
|
||||
typedef struct _zend_trait_method_reference zend_trait_method_reference;
|
||||
|
||||
struct _zend_trait_precedence {
|
||||
zend_trait_method_reference *trait_method;
|
||||
union {
|
||||
zend_class_entry *ce;
|
||||
zend_string *class_name;
|
||||
} *exclude_from_classes;
|
||||
zend_trait_method_reference *trait_method;
|
||||
|
||||
zend_class_entry** exclude_from_classes;
|
||||
};
|
||||
typedef struct _zend_trait_precedence zend_trait_precedence;
|
||||
|
||||
@@ -458,27 +465,29 @@ struct _zend_trait_alias {
|
||||
/**
|
||||
* name for method to be added
|
||||
*/
|
||||
zend_string *alias;
|
||||
const char* alias;
|
||||
unsigned int alias_len;
|
||||
|
||||
/**
|
||||
* modifiers to be set on trait method
|
||||
*/
|
||||
uint32_t modifiers;
|
||||
zend_uint modifiers;
|
||||
};
|
||||
typedef struct _zend_trait_alias zend_trait_alias;
|
||||
|
||||
struct _zend_class_entry {
|
||||
char type;
|
||||
zend_string *name;
|
||||
const char *name;
|
||||
zend_uint name_length;
|
||||
struct _zend_class_entry *parent;
|
||||
int refcount;
|
||||
uint32_t ce_flags;
|
||||
zend_uint ce_flags;
|
||||
|
||||
HashTable function_table;
|
||||
HashTable properties_info;
|
||||
zval *default_properties_table;
|
||||
zval *default_static_members_table;
|
||||
zval *static_members_table;
|
||||
zval **default_properties_table;
|
||||
zval **default_static_members_table;
|
||||
zval **static_members_table;
|
||||
HashTable constants_table;
|
||||
int default_properties_count;
|
||||
int default_static_members_count;
|
||||
@@ -500,29 +509,30 @@ struct _zend_class_entry {
|
||||
zend_class_iterator_funcs iterator_funcs;
|
||||
|
||||
/* handlers */
|
||||
zend_object* (*create_object)(zend_class_entry *class_type TSRMLS_DC);
|
||||
zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);
|
||||
zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
|
||||
int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */
|
||||
union _zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method TSRMLS_DC);
|
||||
union _zend_function *(*get_static_method)(zend_class_entry *ce, char* method, int method_len TSRMLS_DC);
|
||||
|
||||
/* serializer callbacks */
|
||||
int (*serialize)(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC);
|
||||
int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC);
|
||||
int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
|
||||
int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
|
||||
|
||||
zend_class_entry **interfaces;
|
||||
uint32_t num_interfaces;
|
||||
zend_uint num_interfaces;
|
||||
|
||||
zend_class_entry **traits;
|
||||
uint32_t num_traits;
|
||||
zend_uint num_traits;
|
||||
zend_trait_alias **trait_aliases;
|
||||
zend_trait_precedence **trait_precedences;
|
||||
|
||||
union {
|
||||
struct {
|
||||
zend_string *filename;
|
||||
uint32_t line_start;
|
||||
uint32_t line_end;
|
||||
zend_string *doc_comment;
|
||||
const char *filename;
|
||||
zend_uint line_start;
|
||||
zend_uint line_end;
|
||||
const char *doc_comment;
|
||||
zend_uint doc_comment_len;
|
||||
} user;
|
||||
struct {
|
||||
const struct _zend_function_entry *builtin_functions;
|
||||
@@ -534,18 +544,17 @@ struct _zend_class_entry {
|
||||
#include "zend_stream.h"
|
||||
typedef struct _zend_utility_functions {
|
||||
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
|
||||
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
size_t (*write_function)(const char *str, size_t str_length);
|
||||
int (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
int (*write_function)(const char *str, uint str_length);
|
||||
FILE *(*fopen_function)(const char *filename, char **opened_path TSRMLS_DC);
|
||||
void (*message_handler)(long message, const void *data TSRMLS_DC);
|
||||
void (*block_interruptions)(void);
|
||||
void (*unblock_interruptions)(void);
|
||||
int (*get_configuration_directive)(const char *name, uint name_length, zval *contents);
|
||||
void (*ticks_function)(int ticks TSRMLS_DC);
|
||||
void (*ticks_function)(int ticks);
|
||||
void (*on_timeout)(int seconds TSRMLS_DC);
|
||||
int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
|
||||
size_t (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
zend_string *(*vstrpprintf_function)(size_t max_len, const char *format, va_list ap);
|
||||
int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
|
||||
char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC);
|
||||
} zend_utility_functions;
|
||||
@@ -569,6 +578,33 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
|
||||
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
|
||||
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
|
||||
|
||||
/* data types */
|
||||
/* All data types <= IS_BOOL have their constructor/destructors skipped */
|
||||
#define IS_NULL 0
|
||||
#define IS_LONG 1
|
||||
#define IS_DOUBLE 2
|
||||
#define IS_BOOL 3
|
||||
#define IS_ARRAY 4
|
||||
#define IS_OBJECT 5
|
||||
#define IS_STRING 6
|
||||
#define IS_RESOURCE 7
|
||||
#define IS_CONSTANT 8
|
||||
#define IS_CONSTANT_AST 9
|
||||
#define IS_CALLABLE 10
|
||||
|
||||
#define IS_CONSTANT_TYPE_MASK 0x00f
|
||||
#define IS_CONSTANT_UNQUALIFIED 0x010
|
||||
#define IS_LEXICAL_VAR 0x020
|
||||
#define IS_LEXICAL_REF 0x040
|
||||
#define IS_CONSTANT_IN_NAMESPACE 0x100
|
||||
|
||||
#define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
|
||||
|
||||
/* overloaded elements data types */
|
||||
#define OE_IS_ARRAY (1<<0)
|
||||
#define OE_IS_OBJECT (1<<1)
|
||||
#define OE_IS_METHOD (1<<2)
|
||||
|
||||
int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC);
|
||||
void zend_shutdown(TSRMLS_D);
|
||||
void zend_register_standard_ini_entries(TSRMLS_D);
|
||||
@@ -609,9 +645,9 @@ END_EXTERN_C()
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API char *get_zend_version(void);
|
||||
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC);
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC);
|
||||
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
|
||||
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent);
|
||||
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
|
||||
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
|
||||
ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC);
|
||||
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
|
||||
@@ -635,9 +671,22 @@ END_EXTERN_C()
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API void free_estring(char **str_p);
|
||||
ZEND_API void free_string_zval(zval *zv);
|
||||
END_EXTERN_C()
|
||||
|
||||
/* FIXME: Check if we can save if (ptr) too */
|
||||
|
||||
#define STR_FREE(ptr) if (ptr) { str_efree(ptr); }
|
||||
#define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); }
|
||||
|
||||
#ifndef ZTS
|
||||
#define STR_EMPTY_ALLOC() CG(interned_empty_string)? CG(interned_empty_string) : estrndup("", sizeof("")-1)
|
||||
#else
|
||||
#define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1)
|
||||
#endif
|
||||
|
||||
#define STR_REALLOC(ptr, size) \
|
||||
ptr = (char *) erealloc(ptr, size);
|
||||
|
||||
/* output support */
|
||||
#define ZEND_WRITE(str, str_len) zend_write((str), (str_len))
|
||||
#define ZEND_WRITE_EX(str, str_len) write_func((str), (str_len))
|
||||
@@ -646,17 +695,16 @@ END_EXTERN_C()
|
||||
#define ZEND_PUTC(c) zend_write(&(c), 1)
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
extern ZEND_API size_t (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
extern ZEND_API zend_write_func_t zend_write;
|
||||
extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC);
|
||||
extern ZEND_API void (*zend_block_interruptions)(void);
|
||||
extern ZEND_API void (*zend_unblock_interruptions)(void);
|
||||
extern ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC);
|
||||
extern ZEND_API void (*zend_ticks_function)(int ticks);
|
||||
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
|
||||
extern ZEND_API void (*zend_on_timeout)(int seconds TSRMLS_DC);
|
||||
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
|
||||
extern size_t (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
extern zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
|
||||
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
|
||||
extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
|
||||
|
||||
@@ -685,7 +733,7 @@ END_EXTERN_C()
|
||||
#endif
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_message_dispatcher(zend_long message, const void *data TSRMLS_DC);
|
||||
ZEND_API void zend_message_dispatcher(long message, const void *data TSRMLS_DC);
|
||||
|
||||
ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents);
|
||||
END_EXTERN_C()
|
||||
@@ -699,127 +747,101 @@ END_EXTERN_C()
|
||||
#define ZMSG_LOG_SCRIPT_NAME 6L
|
||||
#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL 7L
|
||||
|
||||
#define ZVAL_COPY_VALUE(z, v) \
|
||||
do { \
|
||||
zval *_z1 = (z); \
|
||||
zval *_z2 = (v); \
|
||||
(_z1)->value = (_z2)->value; \
|
||||
Z_TYPE_INFO_P(_z1) = Z_TYPE_INFO_P(_z2); \
|
||||
#define INIT_PZVAL(z) \
|
||||
(z)->refcount__gc = 1; \
|
||||
(z)->is_ref__gc = 0;
|
||||
|
||||
#define INIT_ZVAL(z) z = zval_used_for_init;
|
||||
|
||||
#define ALLOC_INIT_ZVAL(zp) \
|
||||
ALLOC_ZVAL(zp); \
|
||||
INIT_ZVAL(*zp);
|
||||
|
||||
#define MAKE_STD_ZVAL(zv) \
|
||||
ALLOC_ZVAL(zv); \
|
||||
INIT_PZVAL(zv);
|
||||
|
||||
#define PZVAL_IS_REF(z) Z_ISREF_P(z)
|
||||
|
||||
#define ZVAL_COPY_VALUE(z, v) \
|
||||
do { \
|
||||
(z)->value = (v)->value; \
|
||||
Z_TYPE_P(z) = Z_TYPE_P(v); \
|
||||
} while (0)
|
||||
|
||||
#define ZVAL_COPY(z, v) \
|
||||
do { \
|
||||
zval *__z1 = (z); \
|
||||
zval *__z2 = (v); \
|
||||
ZVAL_COPY_VALUE(__z1, __z2); \
|
||||
if (Z_OPT_REFCOUNTED_P(__z1)) { \
|
||||
Z_ADDREF_P(__z1); \
|
||||
} \
|
||||
#define INIT_PZVAL_COPY(z, v) \
|
||||
do { \
|
||||
ZVAL_COPY_VALUE(z, v); \
|
||||
Z_SET_REFCOUNT_P(z, 1); \
|
||||
Z_UNSET_ISREF_P(z); \
|
||||
} while (0)
|
||||
|
||||
#define ZVAL_DUP(z, v) \
|
||||
do { \
|
||||
zval *__z1 = (z); \
|
||||
zval *__z2 = (v); \
|
||||
ZVAL_COPY_VALUE(__z1, __z2); \
|
||||
zval_opt_copy_ctor(__z1); \
|
||||
#define SEPARATE_ZVAL(ppzv) \
|
||||
do { \
|
||||
if (Z_REFCOUNT_PP((ppzv)) > 1) { \
|
||||
zval *new_zv; \
|
||||
Z_DELREF_PP(ppzv); \
|
||||
ALLOC_ZVAL(new_zv); \
|
||||
INIT_PZVAL_COPY(new_zv, *(ppzv)); \
|
||||
*(ppzv) = new_zv; \
|
||||
zval_copy_ctor(new_zv); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ZVAL_DEREF(z) do { \
|
||||
if (UNEXPECTED(Z_ISREF_P(z))) { \
|
||||
(z) = Z_REFVAL_P(z); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \
|
||||
if (!PZVAL_IS_REF(*ppzv)) { \
|
||||
SEPARATE_ZVAL(ppzv); \
|
||||
}
|
||||
|
||||
#define ZVAL_MAKE_REF(zv) do { \
|
||||
zval *__zv = (zv); \
|
||||
if (!Z_ISREF_P(__zv)) { \
|
||||
ZVAL_NEW_REF(__zv, __zv); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \
|
||||
if (!PZVAL_IS_REF(*ppzv)) { \
|
||||
SEPARATE_ZVAL(ppzv); \
|
||||
Z_SET_ISREF_PP((ppzv)); \
|
||||
}
|
||||
|
||||
#define ZVAL_UNREF(z) do { \
|
||||
zval *_z = (z); \
|
||||
zend_reference *ref; \
|
||||
ZEND_ASSERT(Z_ISREF_P(_z)); \
|
||||
ref = Z_REF_P(_z); \
|
||||
ZVAL_COPY_VALUE(_z, &ref->val); \
|
||||
efree(ref); \
|
||||
} while (0)
|
||||
#define COPY_PZVAL_TO_ZVAL(zv, pzv) \
|
||||
(zv) = *(pzv); \
|
||||
if (Z_REFCOUNT_P(pzv)>1) { \
|
||||
zval_copy_ctor(&(zv)); \
|
||||
Z_DELREF_P((pzv)); \
|
||||
} else { \
|
||||
FREE_ZVAL(pzv); \
|
||||
} \
|
||||
INIT_PZVAL(&(zv));
|
||||
|
||||
#define MAKE_COPY_ZVAL(ppzv, pzv) \
|
||||
INIT_PZVAL_COPY(pzv, *(ppzv)); \
|
||||
zval_copy_ctor((pzv));
|
||||
|
||||
#define SEPARATE_STRING(zv) do { \
|
||||
zval *_zv = (zv); \
|
||||
if (Z_REFCOUNTED_P(_zv) && \
|
||||
Z_REFCOUNT_P(_zv) > 1) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
zval_copy_ctor_func(_zv); \
|
||||
} \
|
||||
} while (0)
|
||||
#define REPLACE_ZVAL_VALUE(ppzv_dest, pzv_src, copy) { \
|
||||
int is_ref, refcount; \
|
||||
\
|
||||
SEPARATE_ZVAL_IF_NOT_REF(ppzv_dest); \
|
||||
is_ref = Z_ISREF_PP(ppzv_dest); \
|
||||
refcount = Z_REFCOUNT_PP(ppzv_dest); \
|
||||
zval_dtor(*ppzv_dest); \
|
||||
ZVAL_COPY_VALUE(*ppzv_dest, pzv_src); \
|
||||
if (copy) { \
|
||||
zval_copy_ctor(*ppzv_dest); \
|
||||
} \
|
||||
Z_SET_ISREF_TO_PP(ppzv_dest, is_ref); \
|
||||
Z_SET_REFCOUNT_PP(ppzv_dest, refcount); \
|
||||
}
|
||||
|
||||
#define SEPARATE_ARRAY(zv) do { \
|
||||
zval *_zv = (zv); \
|
||||
if (Z_REFCOUNT_P(_zv) > 1) { \
|
||||
if (!Z_IMMUTABLE_P(_zv)) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
} \
|
||||
zval_copy_ctor_func(_zv); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEPARATE_ZVAL_NOREF(zv) do { \
|
||||
zval *_zv = (zv); \
|
||||
if (Z_COPYABLE_P(_zv) || \
|
||||
Z_IMMUTABLE_P(_zv)) { \
|
||||
if (Z_REFCOUNT_P(_zv) > 1) { \
|
||||
if (!Z_IMMUTABLE_P(_zv)) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
} \
|
||||
zval_copy_ctor_func(_zv); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEPARATE_ZVAL(zv) do { \
|
||||
zval *_zv = (zv); \
|
||||
if (Z_REFCOUNTED_P(_zv) || \
|
||||
Z_IMMUTABLE_P(_zv)) { \
|
||||
if (Z_REFCOUNT_P(_zv) > 1) { \
|
||||
if (Z_COPYABLE_P(_zv) || \
|
||||
Z_IMMUTABLE_P(_zv)) { \
|
||||
if (!Z_IMMUTABLE_P(_zv)) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
} \
|
||||
zval_copy_ctor_func(_zv); \
|
||||
} else if (Z_ISREF_P(_zv)) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
ZVAL_DUP(_zv, Z_REFVAL_P(_zv)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEPARATE_ZVAL_IF_NOT_REF(zv) do { \
|
||||
zval *_zv = (zv); \
|
||||
if (Z_COPYABLE_P(_zv) || \
|
||||
Z_IMMUTABLE_P(_zv)) { \
|
||||
if (Z_REFCOUNT_P(_zv) > 1) { \
|
||||
if (!Z_IMMUTABLE_P(_zv)) { \
|
||||
Z_DELREF_P(_zv); \
|
||||
} \
|
||||
zval_copy_ctor_func(_zv); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEPARATE_ARG_IF_REF(varptr) do { \
|
||||
ZVAL_DEREF(varptr); \
|
||||
if (Z_REFCOUNTED_P(varptr)) { \
|
||||
Z_ADDREF_P(varptr); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SEPARATE_ARG_IF_REF(varptr) \
|
||||
if (PZVAL_IS_REF(varptr)) { \
|
||||
zval *original_var = varptr; \
|
||||
ALLOC_ZVAL(varptr); \
|
||||
INIT_PZVAL_COPY(varptr, original_var); \
|
||||
zval_copy_ctor(varptr); \
|
||||
} else { \
|
||||
Z_ADDREF_P(varptr); \
|
||||
}
|
||||
|
||||
#define READY_TO_DESTROY(zv) \
|
||||
(Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) == 1)
|
||||
(Z_REFCOUNT_P(zv) == 1 && \
|
||||
(Z_TYPE_P(zv) != IS_OBJECT || \
|
||||
zend_objects_store_get_refcount(zv TSRMLS_CC) == 1))
|
||||
|
||||
#define ZEND_MAX_RESERVED_RESOURCES 4
|
||||
|
||||
@@ -836,7 +858,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
zend_error_handling_t handling;
|
||||
zend_class_entry *exception;
|
||||
zval user_handler;
|
||||
zval *user_handler;
|
||||
} zend_error_handling;
|
||||
|
||||
ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC);
|
||||
|
||||
+1245
-1348
File diff suppressed because it is too large.
Load diff
+250
-795
File diff suppressed because it is too large.
Load diff
+23
-32
@@ -1231,9 +1231,9 @@ ZEND_API zend_mm_heap *zend_mm_startup(void)
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
static zend_long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
|
||||
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
|
||||
{
|
||||
zend_long leaks = 0;
|
||||
long leaks = 0;
|
||||
zend_mm_block *p, *q;
|
||||
|
||||
p = ZEND_MM_NEXT_BLOCK(b);
|
||||
@@ -1276,7 +1276,7 @@ static void zend_mm_check_leaks(zend_mm_heap *heap TSRMLS_DC)
|
||||
{
|
||||
zend_mm_segment *segment = heap->segments_list;
|
||||
zend_mm_block *p, *q;
|
||||
uint32_t total = 0;
|
||||
zend_uint total = 0;
|
||||
|
||||
if (!segment) {
|
||||
return;
|
||||
@@ -1291,7 +1291,7 @@ static void zend_mm_check_leaks(zend_mm_heap *heap TSRMLS_DC)
|
||||
}
|
||||
if (!ZEND_MM_IS_FREE_BLOCK(p)) {
|
||||
if (p->magic == MEM_BLOCK_VALID) {
|
||||
zend_long repeated;
|
||||
long repeated;
|
||||
zend_leak_info leak;
|
||||
|
||||
ZEND_MM_SET_MAGIC(p, MEM_BLOCK_LEAK);
|
||||
@@ -1373,7 +1373,7 @@ static int zend_mm_check_ptr(zend_mm_heap *heap, void *ptr, int silent ZEND_FILE
|
||||
#ifdef ZTS
|
||||
if (ZEND_MM_BAD_THREAD_ID(p)) {
|
||||
if (!silent) {
|
||||
zend_debug_alloc_output("Invalid pointer: ((thread_id=0x%0.8X) != (expected=0x%0.8X))\n", (zend_long)p->thread_id, (zend_long)tsrm_thread_id());
|
||||
zend_debug_alloc_output("Invalid pointer: ((thread_id=0x%0.8X) != (expected=0x%0.8X))\n", (long)p->thread_id, (long)tsrm_thread_id());
|
||||
had_problems = 1;
|
||||
} else {
|
||||
return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
@@ -1758,22 +1758,11 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
uint error_lineno;
|
||||
TSRMLS_FETCH();
|
||||
if (zend_is_compiling(TSRMLS_C)) {
|
||||
zend_string *str = zend_get_compiled_filename(TSRMLS_C);
|
||||
error_filename = str ? str->val : NULL;
|
||||
error_filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
|
||||
} else if (EG(current_execute_data)) {
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
ex = ex->prev_execute_data;
|
||||
}
|
||||
if (ex) {
|
||||
error_filename = ex->func->op_array.filename->val;
|
||||
error_lineno = ex->opline->lineno;
|
||||
} else {
|
||||
error_filename = NULL;
|
||||
error_lineno = 0;
|
||||
}
|
||||
} else if (EG(in_execution)) {
|
||||
error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
|
||||
error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
|
||||
} else {
|
||||
error_filename = NULL;
|
||||
error_lineno = 0;
|
||||
@@ -1984,9 +1973,9 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
||||
#endif
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
#if ZEND_DEBUG
|
||||
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted at %s:%d (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, __zend_filename, __zend_lineno, size);
|
||||
zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %lu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
|
||||
#else
|
||||
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, size);
|
||||
zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", heap->limit, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2297,9 +2286,9 @@ realloc_segment:
|
||||
#endif
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
#if ZEND_DEBUG
|
||||
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted at %s:%d (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, __zend_filename, __zend_lineno, size);
|
||||
zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %ld bytes)", heap->limit, __zend_filename, __zend_lineno, size);
|
||||
#else
|
||||
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, size);
|
||||
zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %ld bytes)", heap->limit, size);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
@@ -2474,7 +2463,7 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res = nmemb;
|
||||
zend_ulong overflow = 0;
|
||||
unsigned long overflow = 0;
|
||||
|
||||
__asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
|
||||
: "=&a"(res), "=&d" (overflow)
|
||||
@@ -2494,7 +2483,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res = nmemb;
|
||||
zend_ulong overflow = 0;
|
||||
unsigned long overflow = 0;
|
||||
|
||||
#ifdef __ILP32__ /* x32 */
|
||||
# define LP_SUFF "l"
|
||||
@@ -2523,7 +2512,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res;
|
||||
zend_ulong overflow;
|
||||
unsigned long overflow;
|
||||
|
||||
__asm__ ("umlal %0,%1,%2,%3"
|
||||
: "=r"(res), "=r"(overflow)
|
||||
@@ -2544,7 +2533,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
{
|
||||
size_t res;
|
||||
zend_ulong overflow;
|
||||
unsigned long overflow;
|
||||
|
||||
__asm__ ("mul %0,%2,%3\n\tumulh %1,%2,%3\n\tadds %0,%0,%4\n\tadc %1,%1,xzr"
|
||||
: "=&r"(res), "=&r"(overflow)
|
||||
@@ -2630,7 +2619,7 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
|
||||
|
||||
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
size_t length;
|
||||
int length;
|
||||
char *p;
|
||||
#ifdef ZEND_SIGNALS
|
||||
TSRMLS_FETCH();
|
||||
@@ -2649,7 +2638,7 @@ ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
return p;
|
||||
}
|
||||
|
||||
ZEND_API char *_estrndup(const char *s, size_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
char *p;
|
||||
#ifdef ZEND_SIGNALS
|
||||
@@ -2670,7 +2659,7 @@ ZEND_API char *_estrndup(const char *s, size_t length ZEND_FILE_LINE_DC ZEND_FIL
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, size_t length)
|
||||
ZEND_API char *zend_strndup(const char *s, uint length)
|
||||
{
|
||||
char *p;
|
||||
#ifdef ZEND_SIGNALS
|
||||
@@ -2693,8 +2682,10 @@ ZEND_API char *zend_strndup(const char *s, size_t length)
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_set_memory_limit(size_t memory_limit TSRMLS_DC)
|
||||
ZEND_API int zend_set_memory_limit(size_t memory_limit)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
AG(mm_heap)->limit = (memory_limit >= AG(mm_heap)->block_size) ? memory_limit : AG(mm_heap)->block_size;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
+26
-11
@@ -26,21 +26,20 @@
|
||||
|
||||
#include "../TSRM/TSRM.h"
|
||||
#include "zend.h"
|
||||
#include "zend_types.h"
|
||||
|
||||
#ifndef ZEND_MM_ALIGNMENT
|
||||
# define ZEND_MM_ALIGNMENT Z_L(8)
|
||||
# define ZEND_MM_ALIGNMENT_LOG2 Z_L(3)
|
||||
#elif ZEND_MM_ALIGNMENT < Z_L(4)
|
||||
# define ZEND_MM_ALIGNMENT 8
|
||||
# define ZEND_MM_ALIGNMENT_LOG2 3
|
||||
#elif ZEND_MM_ALIGNMENT < 4
|
||||
# undef ZEND_MM_ALIGNMENT
|
||||
# undef ZEND_MM_ALIGNMENT_LOG2
|
||||
# define ZEND_MM_ALIGNMENT Z_L(4)
|
||||
# define ZEND_MM_ALIGNMENT_LOG2 Z_L(2)
|
||||
# define ZEND_MM_ALIGNMENT 4
|
||||
# define ZEND_MM_ALIGNMENT_LOG2 2
|
||||
#endif
|
||||
|
||||
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-Z_L(1))
|
||||
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
|
||||
|
||||
#define ZEND_MM_ALIGNED_SIZE(size) (((size) + ZEND_MM_ALIGNMENT - Z_L(1)) & ZEND_MM_ALIGNMENT_MASK)
|
||||
#define ZEND_MM_ALIGNED_SIZE(size) (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
|
||||
|
||||
typedef struct _zend_leak_info {
|
||||
void *addr;
|
||||
@@ -53,7 +52,7 @@ typedef struct _zend_leak_info {
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, size_t length) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
|
||||
|
||||
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
|
||||
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
@@ -64,7 +63,7 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LIN
|
||||
ZEND_API void *_safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
|
||||
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API char *_estrndup(const char *s, size_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
|
||||
/* Standard wrapper macros */
|
||||
@@ -137,7 +136,10 @@ inline static void * __zend_realloc(void *p, size_t len)
|
||||
#define perealloc_recoverable_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_recoverable_rel((ptr), (size)))
|
||||
#define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))
|
||||
|
||||
ZEND_API int zend_set_memory_limit(size_t memory_limit TSRMLS_DC);
|
||||
#define safe_estrdup(ptr) ((ptr)?(estrdup(ptr)):STR_EMPTY_ALLOC())
|
||||
#define safe_estrndup(ptr, len) ((ptr)?(estrndup((ptr), (len))):STR_EMPTY_ALLOC())
|
||||
|
||||
ZEND_API int zend_set_memory_limit(size_t memory_limit);
|
||||
|
||||
ZEND_API void start_memory_manager(TSRMLS_D);
|
||||
ZEND_API void shutdown_memory_manager(int silent, int full_shutdown TSRMLS_DC);
|
||||
@@ -159,6 +161,19 @@ ZEND_API size_t zend_memory_peak_usage(int real_usage TSRMLS_DC);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
/* fast cache for zval's */
|
||||
#define ALLOC_ZVAL(z) \
|
||||
(z) = (zval *) emalloc(sizeof(zval))
|
||||
|
||||
#define FREE_ZVAL(z) \
|
||||
efree_rel(z)
|
||||
|
||||
#define ALLOC_ZVAL_REL(z) \
|
||||
(z) = (zval *) emalloc_rel(sizeof(zval))
|
||||
|
||||
#define FREE_ZVAL_REL(z) \
|
||||
efree_rel(z)
|
||||
|
||||
/* fast cache for HashTables */
|
||||
#define ALLOC_HASHTABLE(ht) \
|
||||
(ht) = (HashTable *) emalloc(sizeof(HashTable))
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Dmitry Stogov <dmitry@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id:$ */
|
||||
|
||||
#ifndef _ZEND_ARENA_H_
|
||||
#define _ZEND_ARENA_H_
|
||||
|
||||
#include "zend.h"
|
||||
|
||||
typedef struct _zend_arena zend_arena;
|
||||
|
||||
struct _zend_arena {
|
||||
char *ptr;
|
||||
char *end;
|
||||
zend_arena *prev;
|
||||
};
|
||||
|
||||
static zend_always_inline zend_arena* zend_arena_create(size_t size)
|
||||
{
|
||||
zend_arena *arena = (zend_arena*)emalloc(size);
|
||||
|
||||
arena->ptr = (char*) arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
|
||||
arena->end = (char*) arena + size;
|
||||
arena->prev = NULL;
|
||||
return arena;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_arena_destroy(zend_arena *arena)
|
||||
{
|
||||
do {
|
||||
zend_arena *prev = arena->prev;
|
||||
efree(arena);
|
||||
arena = prev;
|
||||
} while (arena);
|
||||
}
|
||||
|
||||
#define ZEND_ARENA_ALIGNMENT 8U
|
||||
|
||||
static zend_always_inline void* zend_arena_alloc(zend_arena **arena_ptr, size_t size)
|
||||
{
|
||||
zend_arena *arena = *arena_ptr;
|
||||
char *ptr = arena->ptr;
|
||||
|
||||
size = ZEND_MM_ALIGNED_SIZE(size);
|
||||
|
||||
if (EXPECTED(size <= (size_t)(arena->end - ptr))) {
|
||||
arena->ptr = ptr + size;
|
||||
} else {
|
||||
size_t arena_size =
|
||||
UNEXPECTED((size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) > (size_t)(arena->end - (char*) arena)) ?
|
||||
(size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) :
|
||||
(arena->end - (char*) arena);
|
||||
zend_arena *new_arena = (zend_arena*)emalloc(arena_size);
|
||||
|
||||
ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
|
||||
new_arena->ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena)) + size;
|
||||
new_arena->end = (char*) new_arena + arena_size;
|
||||
new_arena->prev = arena;
|
||||
*arena_ptr = new_arena;
|
||||
}
|
||||
|
||||
return (void*) ptr;
|
||||
}
|
||||
|
||||
static zend_always_inline void* zend_arena_calloc(zend_arena **arena_ptr, size_t count, size_t unit_size)
|
||||
{
|
||||
size_t size = unit_size * count;
|
||||
void *ret;
|
||||
|
||||
ZEND_ASSERT(size >= unit_size && size >= count);
|
||||
ret = zend_arena_alloc(arena_ptr, size);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static zend_always_inline void* zend_arena_checkpoint(zend_arena *arena)
|
||||
{
|
||||
return arena->ptr;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *checkpoint)
|
||||
{
|
||||
zend_arena *arena = *arena_ptr;
|
||||
|
||||
while (UNEXPECTED((char*)checkpoint > arena->end) ||
|
||||
UNEXPECTED((char*)checkpoint < (char*)arena)) {
|
||||
zend_arena *prev = arena->prev;
|
||||
efree(arena);
|
||||
*arena_ptr = arena = prev;
|
||||
}
|
||||
arena->ptr = (char*)checkpoint;
|
||||
}
|
||||
|
||||
#endif /* _ZEND_ARENA_H_ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
+27
-53
@@ -28,7 +28,8 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv)
|
||||
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval));
|
||||
ast->kind = ZEND_CONST;
|
||||
ast->children = 0;
|
||||
ZVAL_COPY_VALUE(&ast->u.val, zv);
|
||||
ast->u.val = (zval*)(ast + 1);
|
||||
INIT_PZVAL_COPY(ast->u.val, zv);
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
|
||||
int i;
|
||||
|
||||
if (ast->kind == ZEND_CONST) {
|
||||
return !Z_CONSTANT(ast->u.val);
|
||||
return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val));
|
||||
} else {
|
||||
for (i = 0; i < ast->children; i++) {
|
||||
if ((&ast->u.child)[i]) {
|
||||
@@ -101,37 +102,6 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr TSRMLS_DC)
|
||||
{
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_UNDEF:
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(result), expr);
|
||||
break;
|
||||
case IS_STRING:
|
||||
zend_symtable_update(Z_ARRVAL_P(result), Z_STR_P(offset), expr);
|
||||
zval_dtor(offset);
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_symtable_update(Z_ARRVAL_P(result), STR_EMPTY_ALLOC(), expr);
|
||||
break;
|
||||
case IS_LONG:
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), expr);
|
||||
break;
|
||||
case IS_FALSE:
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), 0, expr);
|
||||
break;
|
||||
case IS_TRUE:
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), 1, expr);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), expr);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_ERROR, "Illegal offset type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC)
|
||||
{
|
||||
zval op1, op2;
|
||||
@@ -283,22 +253,24 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
case ZEND_CONST:
|
||||
/* class constants may be updated in-place */
|
||||
if (scope) {
|
||||
if (Z_OPT_CONSTANT(ast->u.val)) {
|
||||
if (IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val))) {
|
||||
zval_update_constant_ex(&ast->u.val, 1, scope TSRMLS_CC);
|
||||
}
|
||||
ZVAL_DUP(result, &ast->u.val);
|
||||
*result = *ast->u.val;
|
||||
zval_copy_ctor(result);
|
||||
} else {
|
||||
ZVAL_DUP(result, &ast->u.val);
|
||||
if (Z_OPT_CONSTANT_P(result)) {
|
||||
zval_update_constant_ex(result, 1, scope TSRMLS_CC);
|
||||
*result = *ast->u.val;
|
||||
zval_copy_ctor(result);
|
||||
if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
|
||||
zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_BOOL_AND:
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
|
||||
if (zend_is_true(&op1 TSRMLS_CC)) {
|
||||
if (zend_is_true(&op1)) {
|
||||
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
|
||||
ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
|
||||
ZVAL_BOOL(result, zend_is_true(&op2));
|
||||
zval_dtor(&op2);
|
||||
} else {
|
||||
ZVAL_BOOL(result, 0);
|
||||
@@ -307,18 +279,18 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
break;
|
||||
case ZEND_BOOL_OR:
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
|
||||
if (zend_is_true(&op1 TSRMLS_CC)) {
|
||||
if (zend_is_true(&op1)) {
|
||||
ZVAL_BOOL(result, 1);
|
||||
} else {
|
||||
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
|
||||
ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
|
||||
ZVAL_BOOL(result, zend_is_true(&op2));
|
||||
zval_dtor(&op2);
|
||||
}
|
||||
zval_dtor(&op1);
|
||||
break;
|
||||
case ZEND_SELECT:
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
|
||||
if (zend_is_true(&op1 TSRMLS_CC)) {
|
||||
if (zend_is_true(&op1)) {
|
||||
if (!(&ast->u.child)[1]) {
|
||||
*result = op1;
|
||||
} else {
|
||||
@@ -343,17 +315,19 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
zval_dtor(&op2);
|
||||
break;
|
||||
case ZEND_INIT_ARRAY:
|
||||
INIT_PZVAL(result);
|
||||
array_init(result);
|
||||
{
|
||||
int i;
|
||||
zend_bool has_key;
|
||||
for (i = 0; i < ast->children; i+=2) {
|
||||
if ((&ast->u.child)[i]) {
|
||||
zval *expr;
|
||||
MAKE_STD_ZVAL(expr);
|
||||
if ((has_key = !!(&ast->u.child)[i])) {
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
|
||||
} else {
|
||||
ZVAL_UNDEF(&op1);
|
||||
}
|
||||
zend_ast_evaluate(&op2, (&ast->u.child)[i+1], scope TSRMLS_CC);
|
||||
zend_ast_add_array_element(result, &op1, &op2 TSRMLS_CC);
|
||||
zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC);
|
||||
zend_do_add_static_array_element(result, has_key?&op1:NULL, expr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -361,9 +335,9 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
|
||||
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
|
||||
{
|
||||
zval tmp;
|
||||
zval *tmp;
|
||||
zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
|
||||
ZVAL_ZVAL(result, &tmp, 1, 1);
|
||||
ZVAL_ZVAL(result, tmp, 1, 1);
|
||||
}
|
||||
zval_dtor(&op1);
|
||||
zval_dtor(&op2);
|
||||
@@ -378,8 +352,8 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
|
||||
if (ast == NULL) {
|
||||
return NULL;
|
||||
} else if (ast->kind == ZEND_CONST) {
|
||||
zend_ast *copy = zend_ast_create_constant(&ast->u.val);
|
||||
zval_copy_ctor(©->u.val);
|
||||
zend_ast *copy = zend_ast_create_constant(ast->u.val);
|
||||
zval_copy_ctor(copy->u.val);
|
||||
return copy;
|
||||
} else if (ast->children) {
|
||||
zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
|
||||
@@ -399,7 +373,7 @@ ZEND_API void zend_ast_destroy(zend_ast *ast)
|
||||
int i;
|
||||
|
||||
if (ast->kind == ZEND_CONST) {
|
||||
zval_dtor(&ast->u.val);
|
||||
zval_dtor(ast->u.val);
|
||||
} else {
|
||||
for (i = 0; i < ast->children; i++) {
|
||||
if ((&ast->u.child)[i]) {
|
||||
|
||||
+3
-1
@@ -22,6 +22,8 @@
|
||||
#ifndef ZEND_AST_H
|
||||
#define ZEND_AST_H
|
||||
|
||||
typedef struct _zend_ast zend_ast;
|
||||
|
||||
#include "zend.h"
|
||||
|
||||
typedef enum _zend_ast_kind {
|
||||
@@ -38,7 +40,7 @@ struct _zend_ast {
|
||||
unsigned short kind;
|
||||
unsigned short children;
|
||||
union {
|
||||
zval val;
|
||||
zval *val;
|
||||
zend_ast *child;
|
||||
} u;
|
||||
};
|
||||
|
||||
+652
-796
File diff suppressed because it is too large.
Load diff
+127
-102
@@ -37,7 +37,7 @@
|
||||
typedef struct _zend_closure {
|
||||
zend_object std;
|
||||
zend_function func;
|
||||
zval this_ptr;
|
||||
zval *this_ptr;
|
||||
HashTable *debug_info;
|
||||
} zend_closure;
|
||||
|
||||
@@ -47,21 +47,25 @@ static zend_object_handlers closure_handlers;
|
||||
|
||||
ZEND_METHOD(Closure, __invoke) /* {{{ */
|
||||
{
|
||||
zend_function *func = EG(current_execute_data)->func;
|
||||
zval *arguments;
|
||||
zend_function *func = EG(current_execute_data)->function_state.function;
|
||||
zval ***arguments;
|
||||
zval *closure_result_ptr = NULL;
|
||||
|
||||
arguments = emalloc(sizeof(zval) * ZEND_NUM_ARGS());
|
||||
arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
|
||||
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
|
||||
efree(arguments);
|
||||
zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for calling closure");
|
||||
RETVAL_FALSE;
|
||||
} else if (call_user_function_ex(CG(function_table), NULL, getThis(), return_value, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
|
||||
} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
|
||||
RETVAL_FALSE;
|
||||
} else if (closure_result_ptr) {
|
||||
zval_ptr_dtor(&return_value);
|
||||
*return_value_ptr = closure_result_ptr;
|
||||
}
|
||||
efree(arguments);
|
||||
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
zend_string_release(func->internal_function.function_name);
|
||||
efree((char*)func->internal_function.function_name);
|
||||
efree(func);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -72,13 +76,13 @@ ZEND_METHOD(Closure, bind)
|
||||
{
|
||||
zval *newthis, *zclosure, *scope_arg = NULL;
|
||||
zend_closure *closure;
|
||||
zend_class_entry *ce;
|
||||
zend_class_entry *ce, **ce_p;
|
||||
|
||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo!|z", &zclosure, zend_ce_closure, &newthis, &scope_arg) == FAILURE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
closure = (zend_closure *)Z_OBJ_P(zclosure);
|
||||
closure = (zend_closure *)zend_object_store_get_object(zclosure TSRMLS_CC);
|
||||
|
||||
if ((newthis != NULL) && (closure->func.common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
zend_error(E_WARNING, "Cannot bind an instance to a static closure");
|
||||
@@ -90,16 +94,34 @@ ZEND_METHOD(Closure, bind)
|
||||
} else if (Z_TYPE_P(scope_arg) == IS_NULL) {
|
||||
ce = NULL;
|
||||
} else {
|
||||
zend_string *class_name = zval_get_string(scope_arg);
|
||||
if ((class_name->len == sizeof("static") - 1) &&
|
||||
(memcmp("static", class_name->val, sizeof("static") - 1) == 0)) {
|
||||
ce = closure->func.common.scope;
|
||||
} else if ((ce = zend_lookup_class_ex(class_name, NULL, 1 TSRMLS_CC)) == NULL) {
|
||||
zend_error(E_WARNING, "Class '%s' not found", class_name->val);
|
||||
zend_string_release(class_name);
|
||||
RETURN_NULL();
|
||||
char *class_name;
|
||||
int class_name_len;
|
||||
zval tmp_zval;
|
||||
INIT_ZVAL(tmp_zval);
|
||||
|
||||
if (Z_TYPE_P(scope_arg) == IS_STRING) {
|
||||
class_name = Z_STRVAL_P(scope_arg);
|
||||
class_name_len = Z_STRLEN_P(scope_arg);
|
||||
} else {
|
||||
tmp_zval = *scope_arg;
|
||||
zval_copy_ctor(&tmp_zval);
|
||||
convert_to_string(&tmp_zval);
|
||||
class_name = Z_STRVAL(tmp_zval);
|
||||
class_name_len = Z_STRLEN(tmp_zval);
|
||||
}
|
||||
zend_string_release(class_name);
|
||||
|
||||
if ((class_name_len == sizeof("static") - 1) &&
|
||||
(memcmp("static", class_name, sizeof("static") - 1) == 0)) {
|
||||
ce = closure->func.common.scope;
|
||||
}
|
||||
else if (zend_lookup_class_ex(class_name, class_name_len, NULL, 1, &ce_p TSRMLS_CC) == FAILURE) {
|
||||
zend_error(E_WARNING, "Class '%s' not found", class_name);
|
||||
zval_dtor(&tmp_zval);
|
||||
RETURN_NULL();
|
||||
} else {
|
||||
ce = *ce_p;
|
||||
}
|
||||
zval_dtor(&tmp_zval);
|
||||
}
|
||||
} else { /* scope argument not given; do not change the scope by default */
|
||||
ce = closure->func.common.scope;
|
||||
@@ -109,7 +131,7 @@ ZEND_METHOD(Closure, bind)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_function *zend_closure_get_constructor(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not allowed");
|
||||
return NULL;
|
||||
@@ -118,13 +140,13 @@ static zend_function *zend_closure_get_constructor(zend_object *object TSRMLS_DC
|
||||
|
||||
static int zend_closure_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return (Z_OBJ_P(o1) != Z_OBJ_P(o2));
|
||||
return (Z_OBJ_HANDLE_P(o1) != Z_OBJ_HANDLE_P(o2));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)object;
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
|
||||
zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
|
||||
|
||||
invoke->common = closure->func.common;
|
||||
@@ -133,63 +155,65 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object TSRML
|
||||
invoke->internal_function.handler = ZEND_MN(Closure___invoke);
|
||||
invoke->internal_function.module = 0;
|
||||
invoke->internal_function.scope = zend_ce_closure;
|
||||
invoke->internal_function.function_name = zend_string_init(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1, 0);
|
||||
invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
|
||||
return invoke;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
|
||||
return &closure->func;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
|
||||
return &closure->this_ptr;
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
|
||||
return closure->this_ptr;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_function *zend_closure_get_method(zend_object **object, zend_string *method, const zval *key TSRMLS_DC) /* {{{ */
|
||||
static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_string *lc_name;
|
||||
char *lc_name;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
|
||||
lc_name = zend_string_alloc(method->len, 0);
|
||||
zend_str_tolower_copy(lc_name->val, method->val, method->len);
|
||||
if ((method->len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
|
||||
memcmp(lc_name->val, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||
lc_name = do_alloca(method_len + 1, use_heap);
|
||||
zend_str_tolower_copy(lc_name, method_name, method_len);
|
||||
if ((method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
|
||||
memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||
) {
|
||||
zend_string_free(lc_name);
|
||||
return zend_get_closure_invoke_method(*object TSRMLS_CC);
|
||||
free_alloca(lc_name, use_heap);
|
||||
return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
|
||||
}
|
||||
zend_string_free(lc_name);
|
||||
return std_object_handlers.get_method(object, method, key TSRMLS_CC);
|
||||
free_alloca(lc_name, use_heap);
|
||||
return std_object_handlers.get_method(object_ptr, method_name, method_len, key TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *zend_closure_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv TSRMLS_DC) /* {{{ */
|
||||
static zval *zend_closure_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZEND_CLOSURE_PROPERTY_ERROR();
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
return &EG(uninitialized_zval);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_closure_write_property(zval *object, zval *member, zval *value, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
static void zend_closure_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZEND_CLOSURE_PROPERTY_ERROR();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *zend_closure_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZEND_CLOSURE_PROPERTY_ERROR();
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_closure_has_property(zval *object, zval *member, int has_set_exists, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
static int zend_closure_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (has_set_exists != 2) {
|
||||
ZEND_CLOSURE_PROPERTY_ERROR();
|
||||
@@ -198,13 +222,13 @@ static int zend_closure_has_property(zval *object, zval *member, int has_set_exi
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_closure_unset_property(zval *object, zval *member, void **cache_slot TSRMLS_DC) /* {{{ */
|
||||
static void zend_closure_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZEND_CLOSURE_PROPERTY_ERROR();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_closure_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)object;
|
||||
|
||||
@@ -213,7 +237,7 @@ static void zend_closure_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
if (closure->func.type == ZEND_USER_FUNCTION) {
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
while (ex) {
|
||||
if (ex->func == &closure->func) {
|
||||
if (ex->op_array == &closure->func.op_array) {
|
||||
zend_error(E_ERROR, "Cannot destroy active lambda function");
|
||||
}
|
||||
ex = ex->prev_execute_data;
|
||||
@@ -226,37 +250,42 @@ static void zend_closure_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
efree(closure->debug_info);
|
||||
}
|
||||
|
||||
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
|
||||
if (closure->this_ptr) {
|
||||
zval_ptr_dtor(&closure->this_ptr);
|
||||
}
|
||||
|
||||
efree(closure);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_closure_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_closure_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure;
|
||||
zend_object_value object;
|
||||
|
||||
closure = emalloc(sizeof(zend_closure));
|
||||
memset(closure, 0, sizeof(zend_closure));
|
||||
|
||||
zend_object_std_init(&closure->std, class_type TSRMLS_CC);
|
||||
closure->std.handlers = &closure_handlers;
|
||||
|
||||
return (zend_object*)closure;
|
||||
object.handle = zend_objects_store_put(closure, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_closure_free_storage, NULL TSRMLS_CC);
|
||||
object.handlers = &closure_handlers;
|
||||
|
||||
return object;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)Z_OBJ_P(zobject);
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(zobject TSRMLS_CC);
|
||||
zval result;
|
||||
|
||||
zend_create_closure(&result, &closure->func, closure->func.common.scope, &closure->this_ptr TSRMLS_CC);
|
||||
return Z_OBJ(result);
|
||||
zend_create_closure(&result, &closure->func, closure->func.common.scope, closure->this_ptr TSRMLS_CC);
|
||||
return Z_OBJVAL(result);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr TSRMLS_DC) /* {{{ */
|
||||
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure;
|
||||
|
||||
@@ -264,17 +293,17 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
closure = (zend_closure *)Z_OBJ_P(obj);
|
||||
closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
|
||||
*fptr_ptr = &closure->func;
|
||||
|
||||
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
|
||||
if (obj_ptr) {
|
||||
*obj_ptr = Z_OBJ(closure->this_ptr);
|
||||
if (closure->this_ptr) {
|
||||
if (zobj_ptr) {
|
||||
*zobj_ptr = closure->this_ptr;
|
||||
}
|
||||
*ce_ptr = Z_OBJCE(closure->this_ptr);
|
||||
*ce_ptr = Z_OBJCE_P(closure->this_ptr);
|
||||
} else {
|
||||
if (obj_ptr) {
|
||||
*obj_ptr = NULL;
|
||||
if (zobj_ptr) {
|
||||
*zobj_ptr = NULL;
|
||||
}
|
||||
*ce_ptr = closure->func.common.scope;
|
||||
}
|
||||
@@ -284,52 +313,55 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
|
||||
|
||||
static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)Z_OBJ_P(object);
|
||||
zval val;
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(object TSRMLS_CC);
|
||||
zval *val;
|
||||
struct _zend_arg_info *arg_info = closure->func.common.arg_info;
|
||||
|
||||
*is_temp = 0;
|
||||
|
||||
if (closure->debug_info == NULL) {
|
||||
ALLOC_HASHTABLE(closure->debug_info);
|
||||
zend_hash_init(closure->debug_info, 8, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_init(closure->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
if (closure->debug_info->u.v.nApplyCount == 0) {
|
||||
if (closure->debug_info->nApplyCount == 0) {
|
||||
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
|
||||
HashTable *static_variables = closure->func.op_array.static_variables;
|
||||
ZVAL_NEW_ARR(&val);
|
||||
zend_array_dup(Z_ARRVAL(val), static_variables);
|
||||
zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
|
||||
MAKE_STD_ZVAL(val);
|
||||
array_init(val);
|
||||
zend_hash_copy(Z_ARRVAL_P(val), static_variables, (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*));
|
||||
zend_hash_update(closure->debug_info, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
|
||||
Z_ADDREF(closure->this_ptr);
|
||||
zend_hash_str_update(closure->debug_info, "this", sizeof("this")-1, &closure->this_ptr);
|
||||
if (closure->this_ptr) {
|
||||
Z_ADDREF_P(closure->this_ptr);
|
||||
zend_symtable_update(closure->debug_info, "this", sizeof("this"), (void *) &closure->this_ptr, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
if (arg_info) {
|
||||
uint32_t i, required = closure->func.common.required_num_args;
|
||||
zend_uint i, required = closure->func.common.required_num_args;
|
||||
|
||||
array_init(&val);
|
||||
MAKE_STD_ZVAL(val);
|
||||
array_init(val);
|
||||
|
||||
for (i = 0; i < closure->func.common.num_args; i++) {
|
||||
zend_string *name;
|
||||
zval info;
|
||||
char *name, *info;
|
||||
int name_len, info_len;
|
||||
if (arg_info->name) {
|
||||
name = zend_strpprintf(0, "%s$%s",
|
||||
arg_info->pass_by_reference ? "&" : "",
|
||||
arg_info->name);
|
||||
name_len = zend_spprintf(&name, 0, "%s$%s",
|
||||
arg_info->pass_by_reference ? "&" : "",
|
||||
arg_info->name);
|
||||
} else {
|
||||
name = zend_strpprintf(0, "%s$param%d",
|
||||
arg_info->pass_by_reference ? "&" : "",
|
||||
i + 1);
|
||||
name_len = zend_spprintf(&name, 0, "%s$param%d",
|
||||
arg_info->pass_by_reference ? "&" : "",
|
||||
i + 1);
|
||||
}
|
||||
ZVAL_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
|
||||
zend_hash_update(Z_ARRVAL(val), name, &info);
|
||||
zend_string_release(name);
|
||||
info_len = zend_spprintf(&info, 0, "%s",
|
||||
i >= required ? "<optional>" : "<required>");
|
||||
add_assoc_stringl_ex(val, name, name_len + 1, info, info_len, 0);
|
||||
efree(name);
|
||||
arg_info++;
|
||||
}
|
||||
zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);
|
||||
zend_hash_update(closure->debug_info, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,18 +369,12 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static HashTable *zend_closure_get_gc(zval *obj, zval **table, int *n TSRMLS_DC) /* {{{ */
|
||||
static HashTable *zend_closure_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
|
||||
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
|
||||
|
||||
if (closure->debug_info != NULL) {
|
||||
zend_hash_destroy(closure->debug_info);
|
||||
efree(closure->debug_info);
|
||||
closure->debug_info = NULL;
|
||||
}
|
||||
|
||||
*table = Z_TYPE(closure->this_ptr) != IS_NULL ? &closure->this_ptr : NULL;
|
||||
*n = Z_TYPE(closure->this_ptr) != IS_NULL ? 1 : 0;
|
||||
*table = closure->this_ptr ? &closure->this_ptr : NULL;
|
||||
*n = closure->this_ptr ? 1 : 0;
|
||||
return (closure->func.type == ZEND_USER_FUNCTION) ?
|
||||
closure->func.op_array.static_variables : NULL;
|
||||
}
|
||||
@@ -392,8 +418,6 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
|
||||
zend_ce_closure->unserialize = zend_class_unserialize_deny;
|
||||
|
||||
memcpy(&closure_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
closure_handlers.free_obj = zend_closure_free_storage;
|
||||
closure_handlers.clone_obj = NULL;
|
||||
closure_handlers.get_constructor = zend_closure_get_constructor;
|
||||
closure_handlers.get_method = zend_closure_get_method;
|
||||
closure_handlers.write_property = zend_closure_write_property;
|
||||
@@ -415,12 +439,12 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
|
||||
object_init_ex(res, zend_ce_closure);
|
||||
|
||||
closure = (zend_closure *)Z_OBJ_P(res);
|
||||
closure = (zend_closure *)zend_object_store_get_object(res TSRMLS_CC);
|
||||
|
||||
closure->func = *func;
|
||||
closure->func.common.prototype = NULL;
|
||||
|
||||
if ((scope == NULL) && this_ptr && (Z_TYPE_P(this_ptr) != IS_UNDEF)) {
|
||||
if ((scope == NULL) && (this_ptr != NULL)) {
|
||||
/* use dummy scope if we're binding an object without specifying a scope */
|
||||
/* maybe it would be better to create one for this purpose */
|
||||
scope = zend_ce_closure;
|
||||
@@ -432,7 +456,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
|
||||
ALLOC_HASHTABLE(closure->func.op_array.static_variables);
|
||||
zend_hash_init(closure->func.op_array.static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_apply_with_arguments(static_variables TSRMLS_CC, zval_copy_static_var, 1, closure->func.op_array.static_variables);
|
||||
zend_hash_apply_with_arguments(static_variables TSRMLS_CC, (apply_func_args_t)zval_copy_static_var, 1, closure->func.op_array.static_variables);
|
||||
}
|
||||
closure->func.op_array.run_time_cache = NULL;
|
||||
(*closure->func.op_array.refcount)++;
|
||||
@@ -440,12 +464,12 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
/* verify that we aren't binding internal function to a wrong scope */
|
||||
if(func->common.scope != NULL) {
|
||||
if(scope && !instanceof_function(scope, func->common.scope TSRMLS_CC)) {
|
||||
zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name->val, func->common.function_name->val, scope->name->val);
|
||||
zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name, func->common.function_name, scope->name);
|
||||
scope = NULL;
|
||||
}
|
||||
if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 &&
|
||||
!instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope TSRMLS_CC)) {
|
||||
zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name->val, func->common.function_name->val, Z_OBJCE_P(this_ptr)->name->val);
|
||||
zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name, func->common.function_name, Z_OBJCE_P(this_ptr)->name);
|
||||
scope = NULL;
|
||||
this_ptr = NULL;
|
||||
}
|
||||
@@ -456,15 +480,16 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
}
|
||||
}
|
||||
|
||||
ZVAL_UNDEF(&closure->this_ptr);
|
||||
closure->this_ptr = NULL;
|
||||
/* Invariants:
|
||||
* If the closure is unscoped, it has no bound object.
|
||||
* The the closure is scoped, it's either static or it's bound */
|
||||
closure->func.common.scope = scope;
|
||||
if (scope) {
|
||||
closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
|
||||
if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
|
||||
ZVAL_COPY(&closure->this_ptr, this_ptr);
|
||||
if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
|
||||
closure->this_ptr = this_ptr;
|
||||
Z_ADDREF_P(this_ptr);
|
||||
} else {
|
||||
closure->func.common.fn_flags |= ZEND_ACC_STATIC;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ void zend_register_closure_ce(TSRMLS_D);
|
||||
extern ZEND_API zend_class_entry *zend_ce_closure;
|
||||
|
||||
ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zval *this_ptr TSRMLS_DC);
|
||||
ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj TSRMLS_DC);
|
||||
ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC);
|
||||
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC);
|
||||
ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC);
|
||||
|
||||
|
||||
+1268
-1721
File diff suppressed because it is too large.
Load diff
+199
-181
@@ -45,32 +45,45 @@
|
||||
#define RESET_DOC_COMMENT() \
|
||||
{ \
|
||||
if (CG(doc_comment)) { \
|
||||
zend_string_release(CG(doc_comment)); \
|
||||
efree(CG(doc_comment)); \
|
||||
CG(doc_comment) = NULL; \
|
||||
} \
|
||||
CG(doc_comment_len) = 0; \
|
||||
}
|
||||
|
||||
typedef struct _zend_op_array zend_op_array;
|
||||
typedef struct _zend_op zend_op;
|
||||
|
||||
typedef struct _zend_compiler_context {
|
||||
uint32_t opcodes_size;
|
||||
zend_uint opcodes_size;
|
||||
int vars_size;
|
||||
int literals_size;
|
||||
int current_brk_cont;
|
||||
int backpatch_count;
|
||||
int nested_calls;
|
||||
int used_stack;
|
||||
int in_finally;
|
||||
HashTable *labels;
|
||||
} zend_compiler_context;
|
||||
|
||||
typedef struct _zend_literal {
|
||||
zval constant;
|
||||
zend_ulong hash_value;
|
||||
zend_uint cache_slot;
|
||||
} zend_literal;
|
||||
|
||||
#define Z_HASH_P(zv) \
|
||||
(((zend_literal*)(zv))->hash_value)
|
||||
|
||||
typedef union _znode_op {
|
||||
uint32_t constant;
|
||||
uint32_t var;
|
||||
uint32_t num;
|
||||
zend_uint constant;
|
||||
zend_uint var;
|
||||
zend_uint num;
|
||||
zend_ulong hash;
|
||||
uint32_t opline_num; /* Needs to be signed */
|
||||
zend_uint opline_num; /* Needs to be signed */
|
||||
zend_op *jmp_addr;
|
||||
zval *zv;
|
||||
zend_literal *literal;
|
||||
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
|
||||
} znode_op;
|
||||
|
||||
@@ -82,7 +95,7 @@ typedef struct _znode { /* used only during compilation */
|
||||
zend_op_array *op_array;
|
||||
zend_ast *ast;
|
||||
} u;
|
||||
uint32_t EA; /* extended attributes */
|
||||
zend_uint EA; /* extended attributes */
|
||||
} znode;
|
||||
|
||||
typedef struct _zend_execute_data zend_execute_data;
|
||||
@@ -100,7 +113,7 @@ struct _zend_op {
|
||||
znode_op op1;
|
||||
znode_op op2;
|
||||
znode_op result;
|
||||
zend_ulong extended_value;
|
||||
ulong extended_value;
|
||||
uint lineno;
|
||||
zend_uchar opcode;
|
||||
zend_uchar op1_type;
|
||||
@@ -118,24 +131,20 @@ typedef struct _zend_brk_cont_element {
|
||||
|
||||
typedef struct _zend_label {
|
||||
int brk_cont;
|
||||
uint32_t opline_num;
|
||||
zend_uint opline_num;
|
||||
} zend_label;
|
||||
|
||||
typedef struct _zend_try_catch_element {
|
||||
uint32_t try_op;
|
||||
uint32_t catch_op; /* ketchup! */
|
||||
uint32_t finally_op;
|
||||
uint32_t finally_end;
|
||||
zend_uint try_op;
|
||||
zend_uint catch_op; /* ketchup! */
|
||||
zend_uint finally_op;
|
||||
zend_uint finally_end;
|
||||
} zend_try_catch_element;
|
||||
|
||||
#if SIZEOF_ZEND_LONG == 8
|
||||
# ifdef _WIN32
|
||||
# define THIS_HASHVAL 6385726429Ui64
|
||||
# else
|
||||
# define THIS_HASHVAL 6385726429ULL
|
||||
# endif
|
||||
#if SIZEOF_LONG == 8
|
||||
#define THIS_HASHVAL 210728972157UL
|
||||
#else
|
||||
#define THIS_HASHVAL 2090759133UL
|
||||
#define THIS_HASHVAL 275574653UL
|
||||
#endif
|
||||
|
||||
/* method flags (types) */
|
||||
@@ -208,23 +217,26 @@ typedef struct _zend_try_catch_element {
|
||||
/* function has arguments with type hinting */
|
||||
#define ZEND_ACC_HAS_TYPE_HINTS 0x10000000
|
||||
|
||||
char *zend_visibility_string(uint32_t fn_flags);
|
||||
char *zend_visibility_string(zend_uint fn_flags);
|
||||
|
||||
|
||||
typedef struct _zend_property_info {
|
||||
uint32_t flags;
|
||||
zend_string *name;
|
||||
zend_ulong h;
|
||||
zend_uint flags;
|
||||
const char *name;
|
||||
int name_length;
|
||||
ulong h;
|
||||
int offset;
|
||||
zend_string *doc_comment;
|
||||
const char *doc_comment;
|
||||
int doc_comment_len;
|
||||
zend_class_entry *ce;
|
||||
} zend_property_info;
|
||||
|
||||
|
||||
typedef struct _zend_arg_info {
|
||||
const char *name; // TODO: convert into zend_string ???
|
||||
uint32_t name_len;
|
||||
const char *class_name; // TODO: convert into zend_string ???
|
||||
uint32_t class_name_len;
|
||||
const char *name;
|
||||
zend_uint name_len;
|
||||
const char *class_name;
|
||||
zend_uint class_name_len;
|
||||
zend_uchar type_hint;
|
||||
zend_uchar pass_by_reference;
|
||||
zend_bool allow_null;
|
||||
@@ -237,36 +249,45 @@ typedef struct _zend_arg_info {
|
||||
*/
|
||||
typedef struct _zend_internal_function_info {
|
||||
const char *_name;
|
||||
uint32_t _name_len;
|
||||
zend_uint _name_len;
|
||||
const char *_class_name;
|
||||
uint32_t required_num_args;
|
||||
zend_uint required_num_args;
|
||||
zend_uchar _type_hint;
|
||||
zend_bool return_reference;
|
||||
zend_bool _allow_null;
|
||||
zend_bool _is_variadic;
|
||||
} zend_internal_function_info;
|
||||
|
||||
typedef struct _zend_compiled_variable {
|
||||
const char *name;
|
||||
int name_len;
|
||||
ulong hash_value;
|
||||
} zend_compiled_variable;
|
||||
|
||||
struct _zend_op_array {
|
||||
/* Common elements */
|
||||
zend_uchar type;
|
||||
zend_string *function_name;
|
||||
const char *function_name;
|
||||
zend_class_entry *scope;
|
||||
uint32_t fn_flags;
|
||||
zend_function *prototype;
|
||||
uint32_t num_args;
|
||||
uint32_t required_num_args;
|
||||
zend_uint fn_flags;
|
||||
union _zend_function *prototype;
|
||||
zend_uint num_args;
|
||||
zend_uint required_num_args;
|
||||
zend_arg_info *arg_info;
|
||||
/* END of common elements */
|
||||
|
||||
uint32_t *refcount;
|
||||
zend_uint *refcount;
|
||||
|
||||
zend_op *opcodes;
|
||||
uint32_t last;
|
||||
zend_uint last;
|
||||
|
||||
zend_string **vars;
|
||||
zend_compiled_variable *vars;
|
||||
int last_var;
|
||||
|
||||
uint32_t T;
|
||||
zend_uint T;
|
||||
|
||||
zend_uint nested_calls;
|
||||
zend_uint used_stack;
|
||||
|
||||
zend_brk_cont_element *brk_cont_array;
|
||||
int last_brk_cont;
|
||||
@@ -278,15 +299,16 @@ struct _zend_op_array {
|
||||
/* static variables support */
|
||||
HashTable *static_variables;
|
||||
|
||||
uint32_t this_var;
|
||||
zend_uint this_var;
|
||||
|
||||
zend_string *filename;
|
||||
uint32_t line_start;
|
||||
uint32_t line_end;
|
||||
zend_string *doc_comment;
|
||||
uint32_t early_binding; /* the linked list of delayed declarations */
|
||||
const char *filename;
|
||||
zend_uint line_start;
|
||||
zend_uint line_end;
|
||||
const char *doc_comment;
|
||||
zend_uint doc_comment_len;
|
||||
zend_uint early_binding; /* the linked list of delayed declarations */
|
||||
|
||||
zval *literals;
|
||||
zend_literal *literals;
|
||||
int last_literal;
|
||||
|
||||
void **run_time_cache;
|
||||
@@ -302,12 +324,12 @@ struct _zend_op_array {
|
||||
typedef struct _zend_internal_function {
|
||||
/* Common elements */
|
||||
zend_uchar type;
|
||||
zend_string* function_name;
|
||||
const char * function_name;
|
||||
zend_class_entry *scope;
|
||||
uint32_t fn_flags;
|
||||
zend_function *prototype;
|
||||
uint32_t num_args;
|
||||
uint32_t required_num_args;
|
||||
zend_uint fn_flags;
|
||||
union _zend_function *prototype;
|
||||
zend_uint num_args;
|
||||
zend_uint required_num_args;
|
||||
zend_arg_info *arg_info;
|
||||
/* END of common elements */
|
||||
|
||||
@@ -315,30 +337,35 @@ typedef struct _zend_internal_function {
|
||||
struct _zend_module_entry *module;
|
||||
} zend_internal_function;
|
||||
|
||||
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name->val : "")
|
||||
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : "")
|
||||
|
||||
union _zend_function {
|
||||
typedef union _zend_function {
|
||||
zend_uchar type; /* MUST be the first element of this struct! */
|
||||
|
||||
struct {
|
||||
zend_uchar type; /* never used */
|
||||
zend_string *function_name;
|
||||
const char *function_name;
|
||||
zend_class_entry *scope;
|
||||
uint32_t fn_flags;
|
||||
zend_uint fn_flags;
|
||||
union _zend_function *prototype;
|
||||
uint32_t num_args;
|
||||
uint32_t required_num_args;
|
||||
zend_uint num_args;
|
||||
zend_uint required_num_args;
|
||||
zend_arg_info *arg_info;
|
||||
} common;
|
||||
|
||||
zend_op_array op_array;
|
||||
zend_internal_function internal_function;
|
||||
};
|
||||
} zend_function;
|
||||
|
||||
|
||||
typedef struct _zend_function_state {
|
||||
zend_function *function;
|
||||
void **arguments;
|
||||
} zend_function_state;
|
||||
|
||||
typedef struct _zend_function_call_entry {
|
||||
zend_function *fbc;
|
||||
uint32_t op_number;
|
||||
uint32_t arg_num;
|
||||
zend_uint arg_num;
|
||||
zend_bool uses_argument_unpacking;
|
||||
} zend_function_call_entry;
|
||||
|
||||
@@ -355,51 +382,43 @@ typedef struct _list_llist_element {
|
||||
znode value;
|
||||
} list_llist_element;
|
||||
|
||||
typedef enum _vm_frame_kind {
|
||||
VM_FRAME_NESTED_FUNCTION, /* stackless VM call to function */
|
||||
VM_FRAME_NESTED_CODE, /* stackless VM call to include/require/eval */
|
||||
VM_FRAME_TOP_FUNCTION, /* direct VM call to function from external C code */
|
||||
VM_FRAME_TOP_CODE /* direct VM call to "main" code from external C code */
|
||||
} vm_frame_kind;
|
||||
union _temp_variable;
|
||||
|
||||
typedef struct _call_slot {
|
||||
zend_function *fbc;
|
||||
zval *object;
|
||||
zend_class_entry *called_scope;
|
||||
zend_uint num_additional_args;
|
||||
zend_bool is_ctor_call;
|
||||
zend_bool is_ctor_result_used;
|
||||
} call_slot;
|
||||
|
||||
struct _zend_execute_data {
|
||||
struct _zend_op *opline; /* executed opline */
|
||||
zend_execute_data *call; /* current call */
|
||||
void **run_time_cache;
|
||||
zend_function *func; /* executed op_array */
|
||||
uint32_t num_args;
|
||||
zend_uchar flags;
|
||||
zend_uchar frame_kind;
|
||||
zend_class_entry *called_scope;
|
||||
zend_object *object;
|
||||
zend_execute_data *prev_nested_call;
|
||||
zend_execute_data *prev_execute_data;
|
||||
zval *return_value;
|
||||
zend_class_entry *scope; /* function scope (self) */
|
||||
zend_array *symbol_table;
|
||||
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
|
||||
zend_object *delayed_exception;
|
||||
zval old_error_reporting;
|
||||
struct _zend_op *opline;
|
||||
zend_function_state function_state;
|
||||
zend_op_array *op_array;
|
||||
zval *object;
|
||||
HashTable *symbol_table;
|
||||
struct _zend_execute_data *prev_execute_data;
|
||||
zval *old_error_reporting;
|
||||
zend_bool nested;
|
||||
zval **original_return_value;
|
||||
zend_class_entry *current_scope;
|
||||
zend_class_entry *current_called_scope;
|
||||
zval *current_this;
|
||||
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
|
||||
zval *delayed_exception;
|
||||
call_slot *call_slots;
|
||||
call_slot *call;
|
||||
};
|
||||
|
||||
#define ZEND_CALL_CTOR (1 << 0)
|
||||
#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 1)
|
||||
|
||||
#define ZEND_CALL_FRAME_SLOT \
|
||||
((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))
|
||||
|
||||
#define ZEND_CALL_ARG(call, n) \
|
||||
(((zval*)(call)) + ((n) + (ZEND_CALL_FRAME_SLOT - 1)))
|
||||
|
||||
#define EX(element) execute_data.element
|
||||
|
||||
#define EX_VAR_2(ex, n) ((zval*)(((char*)(ex)) + ((int)(n))))
|
||||
#define EX_VAR_NUM_2(ex, n) (((zval*)(ex)) + (ZEND_CALL_FRAME_SLOT + ((int)(n))))
|
||||
#define EX_TMP_VAR(ex, n) ((temp_variable*)(((char*)(ex)) + ((int)(n))))
|
||||
#define EX_TMP_VAR_NUM(ex, n) (EX_TMP_VAR(ex, 0) - (1 + (n)))
|
||||
|
||||
#define EX_VAR(n) EX_VAR_2(execute_data, n)
|
||||
#define EX_VAR_NUM(n) EX_VAR_NUM_2(execute_data, n)
|
||||
#define EX_CV_NUM(ex, n) (((zval***)(((char*)(ex))+ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))))+(n))
|
||||
|
||||
#define EX_VAR_TO_NUM(n) (EX_VAR_2(NULL, n) - EX_VAR_NUM_2(NULL, 0))
|
||||
|
||||
#define IS_CONST (1<<0)
|
||||
#define IS_TMP_VAR (1<<1)
|
||||
@@ -425,9 +444,9 @@ ZEND_API int lex_scan(zval *zendlval TSRMLS_DC);
|
||||
void startup_scanner(TSRMLS_D);
|
||||
void shutdown_scanner(TSRMLS_D);
|
||||
|
||||
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename TSRMLS_DC);
|
||||
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename TSRMLS_DC);
|
||||
ZEND_API zend_string *zend_get_compiled_filename(TSRMLS_D);
|
||||
ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC);
|
||||
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC);
|
||||
ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
|
||||
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
|
||||
ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
|
||||
|
||||
@@ -435,7 +454,7 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace
|
||||
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
||||
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
||||
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
|
||||
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var);
|
||||
ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len);
|
||||
|
||||
#ifdef ZTS
|
||||
const char *zend_get_zendtext(TSRMLS_D);
|
||||
@@ -444,44 +463,44 @@ int zend_get_zendleng(TSRMLS_D);
|
||||
|
||||
|
||||
/* parser-driven code generators */
|
||||
void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
|
||||
void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC);
|
||||
void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
|
||||
void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC);
|
||||
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC);
|
||||
void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC);
|
||||
void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC);
|
||||
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC);
|
||||
void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC);
|
||||
void zend_do_fetch_static_variable(znode *varname, znode *static_assignment, int fetch_type TSRMLS_DC);
|
||||
void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC);
|
||||
void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC);
|
||||
|
||||
void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC);
|
||||
void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC);
|
||||
void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC);
|
||||
void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS_DC);
|
||||
void fetch_string_offset(znode *result, const znode *parent, const znode *offset TSRMLS_DC);
|
||||
void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC);
|
||||
void zend_do_print(znode *result, znode *arg TSRMLS_DC);
|
||||
void zend_do_echo(znode *arg TSRMLS_DC);
|
||||
void zend_do_print(znode *result, const znode *arg TSRMLS_DC);
|
||||
void zend_do_echo(const znode *arg TSRMLS_DC);
|
||||
typedef int (*unary_op_type)(zval *, zval * TSRMLS_DC);
|
||||
typedef int (*binary_op_type)(zval *, zval *, zval * TSRMLS_DC);
|
||||
ZEND_API unary_op_type get_unary_op(int opcode);
|
||||
ZEND_API binary_op_type get_binary_op(int opcode);
|
||||
|
||||
void zend_do_while_cond(znode *expr, znode *close_bracket_token TSRMLS_DC);
|
||||
void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC);
|
||||
void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC);
|
||||
void zend_do_do_while_begin(TSRMLS_D);
|
||||
void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, znode *expr TSRMLS_DC);
|
||||
void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC);
|
||||
|
||||
|
||||
void zend_do_if_cond(znode *cond, znode *closing_bracket_token TSRMLS_DC);
|
||||
void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC);
|
||||
void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC);
|
||||
void zend_do_if_end(TSRMLS_D);
|
||||
|
||||
void zend_do_for_cond(znode *expr, znode *second_semicolon_token TSRMLS_DC);
|
||||
void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC);
|
||||
void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC);
|
||||
void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC);
|
||||
|
||||
void zend_do_pre_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
|
||||
void zend_do_post_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
|
||||
void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC);
|
||||
void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC);
|
||||
|
||||
void zend_do_begin_variable_parse(TSRMLS_D);
|
||||
void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC);
|
||||
@@ -490,23 +509,23 @@ void zend_check_writable_variable(const znode *variable);
|
||||
|
||||
void zend_do_free(znode *op1 TSRMLS_DC);
|
||||
|
||||
void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
|
||||
|
||||
int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier);
|
||||
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
|
||||
void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC);
|
||||
void zend_do_receive_param(zend_uchar op, znode *varname, znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC);
|
||||
void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC);
|
||||
int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC);
|
||||
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
|
||||
void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
|
||||
void zend_do_clone(znode *result, const znode *expr TSRMLS_DC);
|
||||
void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len TSRMLS_DC);
|
||||
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
|
||||
void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC);
|
||||
int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
|
||||
void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC);
|
||||
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
|
||||
void zend_do_yield(znode *result, znode *value, znode *key, zend_bool is_variable TSRMLS_DC);
|
||||
void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC);
|
||||
void zend_do_handle_exception(TSRMLS_D);
|
||||
|
||||
void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC);
|
||||
@@ -518,9 +537,9 @@ void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC);
|
||||
void zend_do_end_catch(znode *catch_token TSRMLS_DC);
|
||||
void zend_do_finally(znode *finally_token TSRMLS_DC);
|
||||
void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC);
|
||||
void zend_do_throw(znode *expr TSRMLS_DC);
|
||||
void zend_do_throw(const znode *expr TSRMLS_DC);
|
||||
|
||||
ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time TSRMLS_DC);
|
||||
ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time);
|
||||
ZEND_API zend_class_entry *do_bind_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
|
||||
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC);
|
||||
@@ -545,24 +564,24 @@ void zend_do_unpack_params(znode *params TSRMLS_DC);
|
||||
|
||||
|
||||
void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC);
|
||||
void zend_do_boolean_or_end(znode *result, znode *expr1, znode *expr2, const znode *op_token TSRMLS_DC);
|
||||
void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC);
|
||||
void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC);
|
||||
void zend_do_boolean_and_end(znode *result, znode *expr1, znode *expr2, const znode *op_token TSRMLS_DC);
|
||||
void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC);
|
||||
|
||||
void zend_do_brk_cont(zend_uchar op, znode *expr TSRMLS_DC);
|
||||
void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC);
|
||||
|
||||
void zend_do_switch_cond(const znode *cond TSRMLS_DC);
|
||||
void zend_do_switch_end(const znode *case_list TSRMLS_DC);
|
||||
void zend_do_case_before_statement(const znode *case_list, znode *case_token, znode *case_expr TSRMLS_DC);
|
||||
void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC);
|
||||
void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC);
|
||||
void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC);
|
||||
|
||||
void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC);
|
||||
void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC);
|
||||
void zend_do_declare_property(znode *var_name, znode *value, uint32_t access_type TSRMLS_DC);
|
||||
void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC);
|
||||
void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC);
|
||||
void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC);
|
||||
|
||||
void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC);
|
||||
void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC);
|
||||
|
||||
void zend_do_halt_compiler_register(TSRMLS_D);
|
||||
|
||||
@@ -575,11 +594,11 @@ void zend_do_end_new_object(znode *result, const znode *new_token TSRMLS_DC);
|
||||
|
||||
void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC);
|
||||
|
||||
void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC);
|
||||
void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC);
|
||||
|
||||
void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC);
|
||||
void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr);
|
||||
void zend_do_list_init(TSRMLS_D);
|
||||
void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
|
||||
void zend_do_add_list_element(const znode *element TSRMLS_DC);
|
||||
@@ -591,13 +610,13 @@ void zend_init_list(void *result, void *item TSRMLS_DC);
|
||||
void zend_add_to_list(void *result, void *item TSRMLS_DC);
|
||||
|
||||
|
||||
void zend_do_cast(znode *result, znode *expr, int type TSRMLS_DC);
|
||||
void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC);
|
||||
void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC);
|
||||
void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC);
|
||||
|
||||
void zend_do_unset(znode *variable TSRMLS_DC);
|
||||
void zend_do_unset(const znode *variable TSRMLS_DC);
|
||||
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
|
||||
|
||||
void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC);
|
||||
void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC);
|
||||
|
||||
void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC);
|
||||
void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC);
|
||||
@@ -607,17 +626,17 @@ void zend_do_declare_begin(TSRMLS_D);
|
||||
void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
|
||||
void zend_do_declare_end(const znode *declare_token TSRMLS_DC);
|
||||
|
||||
void zend_do_exit(znode *result, znode *message TSRMLS_DC);
|
||||
void zend_do_exit(znode *result, const znode *message TSRMLS_DC);
|
||||
|
||||
void zend_do_begin_silence(znode *strudel_token TSRMLS_DC);
|
||||
void zend_do_end_silence(znode *strudel_token TSRMLS_DC);
|
||||
void zend_do_end_silence(const znode *strudel_token TSRMLS_DC);
|
||||
|
||||
void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_jmp_set_else(znode *result, znode *false_value, const znode *jmp_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *jmp_token, const znode *colon_token TSRMLS_DC);
|
||||
|
||||
void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC);
|
||||
void zend_do_qm_true(znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, const znode *colon_token TSRMLS_DC);
|
||||
void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC);
|
||||
void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_token, const znode *colon_token TSRMLS_DC);
|
||||
|
||||
void zend_do_extended_info(TSRMLS_D);
|
||||
void zend_do_extended_fcall_begin(TSRMLS_D);
|
||||
@@ -629,7 +648,7 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const
|
||||
|
||||
void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC);
|
||||
void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC);
|
||||
void zend_do_begin_namespace(znode *name, zend_bool with_brackets TSRMLS_DC);
|
||||
void zend_do_begin_namespace(const znode *name, zend_bool with_brackets TSRMLS_DC);
|
||||
void zend_do_end_namespace(TSRMLS_D);
|
||||
void zend_verify_namespace(TSRMLS_D);
|
||||
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
||||
@@ -642,7 +661,7 @@ void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC);
|
||||
void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC);
|
||||
|
||||
void zend_do_label(znode *label TSRMLS_DC);
|
||||
void zend_do_goto(znode *label TSRMLS_DC);
|
||||
void zend_do_goto(const znode *label TSRMLS_DC);
|
||||
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC);
|
||||
void zend_release_labels(int temporary TSRMLS_DC);
|
||||
|
||||
@@ -656,28 +675,32 @@ ZEND_API void function_add_ref(zend_function *function);
|
||||
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
|
||||
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC);
|
||||
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);
|
||||
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_count, ...);
|
||||
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...);
|
||||
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC);
|
||||
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC);
|
||||
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC);
|
||||
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API int zend_cleanup_user_class_data(zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC);
|
||||
ZEND_API void zend_cleanup_internal_classes(TSRMLS_D);
|
||||
ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array);
|
||||
ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC);
|
||||
ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC);
|
||||
ZEND_API int clean_non_persistent_function_full(zend_function *function TSRMLS_DC);
|
||||
ZEND_API int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC);
|
||||
|
||||
ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
|
||||
ZEND_API void zend_function_dtor(zval *zv);
|
||||
ZEND_API void destroy_zend_class(zval *zv);
|
||||
void zend_class_add_ref(zval *zv);
|
||||
ZEND_API void zend_function_dtor(zend_function *function);
|
||||
ZEND_API void destroy_zend_class(zend_class_entry **pce);
|
||||
void zend_class_add_ref(zend_class_entry **ce);
|
||||
|
||||
ZEND_API zend_string *zend_mangle_property_name(const char *src1, int src1_length, const char *src2, int src2_length, int internal);
|
||||
ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal);
|
||||
#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
|
||||
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
|
||||
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
|
||||
|
||||
#define ZEND_FUNCTION_DTOR zend_function_dtor
|
||||
#define ZEND_CLASS_DTOR destroy_zend_class
|
||||
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
|
||||
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
|
||||
|
||||
zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC);
|
||||
void init_op(zend_op *op TSRMLS_DC);
|
||||
@@ -694,22 +717,24 @@ ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC)
|
||||
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC);
|
||||
int zend_get_class_fetch_type(const char *class_name, uint class_name_len);
|
||||
|
||||
typedef zend_bool (*zend_auto_global_callback)(zend_string *name TSRMLS_DC);
|
||||
typedef zend_bool (*zend_auto_global_callback)(const char *name, uint name_len TSRMLS_DC);
|
||||
typedef struct _zend_auto_global {
|
||||
zend_string *name;
|
||||
const char *name;
|
||||
uint name_len;
|
||||
zend_auto_global_callback auto_global_callback;
|
||||
zend_bool jit;
|
||||
zend_bool armed;
|
||||
} zend_auto_global;
|
||||
|
||||
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
|
||||
ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
|
||||
ZEND_API void zend_activate_auto_globals(TSRMLS_D);
|
||||
ZEND_API zend_bool zend_is_auto_global(zend_string *name TSRMLS_DC);
|
||||
ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC);
|
||||
ZEND_API zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC);
|
||||
ZEND_API size_t zend_dirname(char *path, size_t len);
|
||||
|
||||
int zendlex(znode *zendlval TSRMLS_DC);
|
||||
|
||||
int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
|
||||
|
||||
/* BEGIN: OPCODES */
|
||||
|
||||
@@ -723,10 +748,12 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
#define ZEND_FETCH_CLASS_DEFAULT 0
|
||||
#define ZEND_FETCH_CLASS_SELF 1
|
||||
#define ZEND_FETCH_CLASS_PARENT 2
|
||||
#define ZEND_FETCH_CLASS_STATIC 3
|
||||
#define ZEND_FETCH_CLASS_AUTO 4
|
||||
#define ZEND_FETCH_CLASS_INTERFACE 5
|
||||
#define ZEND_FETCH_CLASS_TRAIT 6
|
||||
#define ZEND_FETCH_CLASS_MAIN 3 /* unused */
|
||||
#define ZEND_FETCH_CLASS_GLOBAL 4 /* unused */
|
||||
#define ZEND_FETCH_CLASS_AUTO 5
|
||||
#define ZEND_FETCH_CLASS_INTERFACE 6
|
||||
#define ZEND_FETCH_CLASS_STATIC 7
|
||||
#define ZEND_FETCH_CLASS_TRAIT 14
|
||||
#define ZEND_FETCH_CLASS_MASK 0x0f
|
||||
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
|
||||
#define ZEND_FETCH_CLASS_SILENT 0x0100
|
||||
@@ -741,6 +768,7 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
#define ZEND_PARSED_NEW (1<<6)
|
||||
#define ZEND_PARSED_LIST_EXPR (1<<7)
|
||||
|
||||
|
||||
/* unset types */
|
||||
#define ZEND_UNSET_REG 0
|
||||
|
||||
@@ -760,9 +788,6 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
#define ZEND_EVAL_CODE 4
|
||||
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
|
||||
|
||||
/* A quick check (type == ZEND_USER_FUNCTION || type == ZEND_EVAL_CODE) */
|
||||
#define ZEND_USER_CODE(type) ((type & 1) == 0)
|
||||
|
||||
#define ZEND_INTERNAL_CLASS 1
|
||||
#define ZEND_USER_CLASS 2
|
||||
|
||||
@@ -815,11 +840,11 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
#define ZEND_SEND_PREFER_REF 2
|
||||
|
||||
#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \
|
||||
(EXPECTED((zf)->common.arg_info != NULL) && \
|
||||
(EXPECTED(arg_num <= (zf)->common.num_args) \
|
||||
((zf)->common.arg_info && \
|
||||
(arg_num <= (zf)->common.num_args \
|
||||
? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \
|
||||
: (UNEXPECTED((zf)->common.fn_flags & ZEND_ACC_VARIADIC) != 0) && \
|
||||
((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m))))
|
||||
: ((zf)->common.fn_flags & ZEND_ACC_VARIADIC) \
|
||||
? ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m)) : 0))
|
||||
|
||||
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
|
||||
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF)
|
||||
@@ -844,10 +869,6 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||
#define ZEND_FAST_CALL_FROM_CATCH 1
|
||||
#define ZEND_FAST_CALL_FROM_FINALLY 2
|
||||
|
||||
#define ZEND_ARRAY_ELEMENT_REF (1<<0)
|
||||
#define ZEND_ARRAY_NOT_PACKED (1<<1)
|
||||
#define ZEND_ARRAY_SIZE_SHIFT 2
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_CLONE_FUNC_NAME "__clone"
|
||||
@@ -873,7 +894,7 @@ END_EXTERN_C()
|
||||
/* call op_array handler of extendions */
|
||||
#define ZEND_COMPILE_HANDLE_OP_ARRAY (1<<1)
|
||||
|
||||
/* generate ZEND_INIT_FCALL_BY_NAME for internal functions instead of ZEND_INIT_FCALL */
|
||||
/* generate ZEND_DO_FCALL_BY_NAME for internal functions instead of ZEND_DO_FCALL */
|
||||
#define ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS (1<<2)
|
||||
|
||||
/* don't perform early binding for classes inherited form internal ones;
|
||||
@@ -887,9 +908,6 @@ END_EXTERN_C()
|
||||
/* disable constant substitution at compile-time */
|
||||
#define ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION (1<<5)
|
||||
|
||||
/* disable usage of builtin instruction for strlen() */
|
||||
#define ZEND_COMPILE_NO_BUILTIN_STRLEN (1<<6)
|
||||
|
||||
/* The default value for CG(compiler_options) */
|
||||
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
|
||||
|
||||
|
||||
+166
-185
@@ -27,67 +27,47 @@
|
||||
#include "zend_globals.h"
|
||||
#include "zend_API.h"
|
||||
|
||||
void free_zend_constant(zval *zv)
|
||||
void free_zend_constant(zend_constant *c)
|
||||
{
|
||||
zend_constant *c = Z_PTR_P(zv);
|
||||
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
zval_dtor(&c->value);
|
||||
} else {
|
||||
zval_internal_dtor(&c->value);
|
||||
}
|
||||
if (c->name) {
|
||||
zend_string_release(c->name);
|
||||
}
|
||||
pefree(c, c->flags & CONST_PERSISTENT);
|
||||
str_free(c->name);
|
||||
}
|
||||
|
||||
|
||||
static void copy_zend_constant(zval *zv)
|
||||
void copy_zend_constant(zend_constant *c)
|
||||
{
|
||||
zend_constant *c = Z_PTR_P(zv);
|
||||
|
||||
Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
|
||||
memcpy(Z_PTR_P(zv), c, sizeof(zend_constant));
|
||||
|
||||
c = Z_PTR_P(zv);
|
||||
c->name = zend_string_copy(c->name);
|
||||
c->name = str_strndup(c->name, c->name_len - 1);
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
zval_copy_ctor(&c->value);
|
||||
} else {
|
||||
if (Z_TYPE(c->value) == IS_STRING) {
|
||||
Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void zend_copy_constants(HashTable *target, HashTable *source)
|
||||
{
|
||||
zend_hash_copy(target, source, copy_zend_constant);
|
||||
zend_constant tmp_constant;
|
||||
|
||||
zend_hash_copy(target, source, (copy_ctor_func_t) copy_zend_constant, &tmp_constant, sizeof(zend_constant));
|
||||
}
|
||||
|
||||
|
||||
static int clean_non_persistent_constant(zval *zv TSRMLS_DC)
|
||||
static int clean_non_persistent_constant(const zend_constant *c TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c = Z_PTR_P(zv);
|
||||
return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
static int clean_non_persistent_constant_full(zval *zv TSRMLS_DC)
|
||||
static int clean_non_persistent_constant_full(const zend_constant *c TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c = Z_PTR_P(zv);
|
||||
return (c->flags & CONST_PERSISTENT) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
static int clean_module_constant(zval *el, void *arg TSRMLS_DC)
|
||||
static int clean_module_constant(const zend_constant *c, int *module_number TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c = (zend_constant *)Z_PTR_P(el);
|
||||
int module_number = *(int *)arg;
|
||||
|
||||
if (c->module_number == module_number) {
|
||||
if (c->module_number == *module_number) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -97,7 +77,7 @@ static int clean_module_constant(zval *el, void *arg TSRMLS_DC)
|
||||
|
||||
void clean_module_constants(int module_number TSRMLS_DC)
|
||||
{
|
||||
zend_hash_apply_with_argument(EG(zend_constants), clean_module_constant, (void *) &module_number TSRMLS_CC);
|
||||
zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) clean_module_constant, (void *) &module_number TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +85,9 @@ int zend_startup_constants(TSRMLS_D)
|
||||
{
|
||||
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
|
||||
|
||||
zend_hash_init(EG(zend_constants), 128, NULL, ZEND_CONSTANT_DTOR, 1);
|
||||
if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -155,9 +137,9 @@ int zend_shutdown_constants(TSRMLS_D)
|
||||
void clean_non_persistent_constants(TSRMLS_D)
|
||||
{
|
||||
if (EG(full_tables_cleanup)) {
|
||||
zend_hash_apply(EG(zend_constants), clean_non_persistent_constant_full TSRMLS_CC);
|
||||
zend_hash_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant_full TSRMLS_CC);
|
||||
} else {
|
||||
zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant TSRMLS_CC);
|
||||
zend_hash_reverse_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +149,8 @@ ZEND_API void zend_register_null_constant(const char *name, uint name_len, int f
|
||||
|
||||
ZVAL_NULL(&c.value);
|
||||
c.flags = flags;
|
||||
c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT);
|
||||
c.name = zend_strndup(name, name_len-1);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c TSRMLS_CC);
|
||||
}
|
||||
@@ -178,18 +161,20 @@ ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_
|
||||
|
||||
ZVAL_BOOL(&c.value, bval);
|
||||
c.flags = flags;
|
||||
c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT);
|
||||
c.name = zend_strndup(name, name_len-1);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API void zend_register_long_constant(const char *name, uint name_len, zend_long lval, int flags, int module_number TSRMLS_DC)
|
||||
ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
ZVAL_LONG(&c.value, lval);
|
||||
c.flags = flags;
|
||||
c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT);
|
||||
c.name = zend_strndup(name, name_len-1);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c TSRMLS_CC);
|
||||
}
|
||||
@@ -201,7 +186,8 @@ ZEND_API void zend_register_double_constant(const char *name, uint name_len, dou
|
||||
|
||||
ZVAL_DOUBLE(&c.value, dval);
|
||||
c.flags = flags;
|
||||
c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT);
|
||||
c.name = zend_strndup(name, name_len-1);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c TSRMLS_CC);
|
||||
}
|
||||
@@ -211,9 +197,10 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
ZVAL_NEW_STR(&c.value, zend_string_init(strval, strlen, flags & CONST_PERSISTENT));
|
||||
ZVAL_STRINGL(&c.value, strval, strlen, 0);
|
||||
c.flags = flags;
|
||||
c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT);
|
||||
c.name = zend_strndup(name, name_len-1);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c TSRMLS_CC);
|
||||
}
|
||||
@@ -224,135 +211,121 @@ ZEND_API void zend_register_string_constant(const char *name, uint name_len, cha
|
||||
zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number TSRMLS_CC);
|
||||
}
|
||||
|
||||
static zend_constant *zend_get_special_constant(const char *name, uint name_len TSRMLS_DC)
|
||||
static int zend_get_special_constant(const char *name, uint name_len, zend_constant **c TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
int ret;
|
||||
static char haltoff[] = "__COMPILER_HALT_OFFSET__";
|
||||
|
||||
if (!EG(current_execute_data)) {
|
||||
return NULL;
|
||||
if (!EG(in_execution)) {
|
||||
return 0;
|
||||
} else if (name_len == sizeof("__CLASS__")-1 &&
|
||||
!memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
|
||||
zend_constant tmp;
|
||||
|
||||
/* Returned constants may be cached, so they have to be stored */
|
||||
if (EG(scope) && EG(scope)->name) {
|
||||
int const_name_len;
|
||||
zend_string *const_name;
|
||||
char *const_name;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
|
||||
const_name_len = sizeof("\0__CLASS__") + EG(scope)->name->len;
|
||||
const_name = zend_string_alloc(const_name_len, 0);
|
||||
memcpy(const_name->val, "\0__CLASS__", sizeof("\0__CLASS__")-1);
|
||||
zend_str_tolower_copy(const_name->val + sizeof("\0__CLASS__")-1, EG(scope)->name->val, EG(scope)->name->len);
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
|
||||
c = emalloc(sizeof(zend_constant));
|
||||
memset(c, 0, sizeof(zend_constant));
|
||||
ZVAL_STR(&c->value, zend_string_copy(EG(scope)->name));
|
||||
zend_hash_add_ptr(EG(zend_constants), const_name, c);
|
||||
const_name_len = sizeof("\0__CLASS__") + EG(scope)->name_length;
|
||||
const_name = do_alloca(const_name_len, use_heap);
|
||||
memcpy(const_name, "\0__CLASS__", sizeof("\0__CLASS__")-1);
|
||||
zend_str_tolower_copy(const_name + sizeof("\0__CLASS__")-1, EG(scope)->name, EG(scope)->name_length);
|
||||
if (zend_hash_find(EG(zend_constants), const_name, const_name_len, (void**)c) == FAILURE) {
|
||||
zend_hash_add(EG(zend_constants), const_name, const_name_len, (void*)&tmp, sizeof(zend_constant), (void**)c);
|
||||
memset(*c, 0, sizeof(zend_constant));
|
||||
Z_STRVAL((**c).value) = estrndup(EG(scope)->name, EG(scope)->name_length);
|
||||
Z_STRLEN((**c).value) = EG(scope)->name_length;
|
||||
Z_TYPE((**c).value) = IS_STRING;
|
||||
}
|
||||
zend_string_release(const_name);
|
||||
free_alloca(const_name, use_heap);
|
||||
} else {
|
||||
zend_string *const_name = zend_string_init("\0__CLASS__", sizeof("\0__CLASS__")-1, 0);
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
|
||||
c = emalloc(sizeof(zend_constant));
|
||||
memset(c, 0, sizeof(zend_constant));
|
||||
ZVAL_EMPTY_STRING(&c->value);
|
||||
zend_hash_add_ptr(EG(zend_constants), const_name, c);
|
||||
if (zend_hash_find(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void**)c) == FAILURE) {
|
||||
zend_hash_add(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void*)&tmp, sizeof(zend_constant), (void**)c);
|
||||
memset(*c, 0, sizeof(zend_constant));
|
||||
Z_STRVAL((**c).value) = estrndup("", 0);
|
||||
Z_STRLEN((**c).value) = 0;
|
||||
Z_TYPE((**c).value) = IS_STRING;
|
||||
}
|
||||
zend_string_release(const_name);
|
||||
}
|
||||
return c;
|
||||
return 1;
|
||||
} else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
|
||||
!memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
|
||||
const char *cfilename;
|
||||
zend_string *haltname;
|
||||
int clen;
|
||||
char *haltname;
|
||||
int len, clen;
|
||||
|
||||
cfilename = zend_get_executed_filename(TSRMLS_C);
|
||||
clen = strlen(cfilename);
|
||||
/* check for __COMPILER_HALT_OFFSET__ */
|
||||
haltname = zend_mangle_property_name(haltoff,
|
||||
zend_mangle_property_name(&haltname, &len, haltoff,
|
||||
sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
|
||||
c = zend_hash_find_ptr(EG(zend_constants), haltname);
|
||||
zend_string_free(haltname);
|
||||
return c;
|
||||
ret = zend_hash_find(EG(zend_constants), haltname, len+1, (void **) c);
|
||||
efree(haltname);
|
||||
return (ret == SUCCESS);
|
||||
} else {
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC)
|
||||
ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
int retval = 1;
|
||||
char *lookup_name;
|
||||
|
||||
if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) {
|
||||
char *lcname = do_alloca(name_len + 1, use_heap);
|
||||
zend_str_tolower_copy(lcname, name, name_len);
|
||||
if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) {
|
||||
if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
|
||||
lookup_name = zend_str_tolower_dup(name, name_len);
|
||||
|
||||
if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
|
||||
if (c->flags & CONST_CS) {
|
||||
c = NULL;
|
||||
retval=0;
|
||||
}
|
||||
} else {
|
||||
c = zend_get_special_constant(name, name_len TSRMLS_CC);
|
||||
retval = zend_get_special_constant(name, name_len, &c TSRMLS_CC);
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
efree(lookup_name);
|
||||
}
|
||||
|
||||
return c ? &c->value : NULL;
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_get_constant(zend_string *name TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), name)) == NULL) {
|
||||
char *lcname = do_alloca(name->len + 1, use_heap);
|
||||
zend_str_tolower_copy(lcname, name->val, name->len);
|
||||
if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name->len)) != NULL) {
|
||||
if (c->flags & CONST_CS) {
|
||||
c = NULL;
|
||||
}
|
||||
} else {
|
||||
c = zend_get_special_constant(name->val, name->len TSRMLS_CC);
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
if (retval) {
|
||||
*result = c->value;
|
||||
zval_copy_ctor(result);
|
||||
Z_SET_REFCOUNT_P(result, 1);
|
||||
Z_UNSET_ISREF_P(result);
|
||||
}
|
||||
|
||||
return c ? &c->value : NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_ulong flags TSRMLS_DC)
|
||||
ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
int retval = 1;
|
||||
const char *colon;
|
||||
zend_class_entry *ce = NULL;
|
||||
zend_string *class_name;
|
||||
const char *name = cname->val;
|
||||
uint name_len = cname->len;
|
||||
char *class_name;
|
||||
zval **ret_constant;
|
||||
|
||||
/* Skip leading \\ */
|
||||
if (name[0] == '\\') {
|
||||
name += 1;
|
||||
name_len -= 1;
|
||||
cname = NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((colon = zend_memrchr(name, ':', name_len)) &&
|
||||
colon > name && (*(colon - 1) == ':')) {
|
||||
int class_name_len = colon - name - 1;
|
||||
int const_name_len = name_len - class_name_len - 2;
|
||||
zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0);
|
||||
const char *constant_name = colon + 1;
|
||||
char *lcname;
|
||||
zval *ret_constant = NULL;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
|
||||
class_name = zend_string_init(name, class_name_len, 0);
|
||||
lcname = do_alloca(class_name_len + 1, use_heap);
|
||||
zend_str_tolower_copy(lcname, name, class_name_len);
|
||||
class_name = estrndup(name, class_name_len);
|
||||
lcname = zend_str_tolower_dup(class_name, class_name_len);
|
||||
if (!scope) {
|
||||
if (EG(current_execute_data)) {
|
||||
if (EG(in_execution)) {
|
||||
scope = EG(scope);
|
||||
} else {
|
||||
scope = CG(active_class_entry);
|
||||
@@ -365,7 +338,9 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
|
||||
ce = scope;
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
|
||||
retval = 0;
|
||||
}
|
||||
efree(lcname);
|
||||
} else if (class_name_len == sizeof("parent")-1 &&
|
||||
!memcmp(lcname, "parent", sizeof("parent")-1)) {
|
||||
if (!scope) {
|
||||
@@ -375,33 +350,31 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
|
||||
} else {
|
||||
ce = scope->parent;
|
||||
}
|
||||
efree(lcname);
|
||||
} else if (class_name_len == sizeof("static")-1 &&
|
||||
!memcmp(lcname, "static", sizeof("static")-1)) {
|
||||
if (EG(current_execute_data) && EG(current_execute_data)->called_scope) {
|
||||
ce = EG(current_execute_data)->called_scope;
|
||||
if (EG(called_scope)) {
|
||||
ce = EG(called_scope);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
|
||||
}
|
||||
efree(lcname);
|
||||
} else {
|
||||
ce = zend_fetch_class(class_name, flags TSRMLS_CC);
|
||||
efree(lcname);
|
||||
ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC);
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
if (ce) {
|
||||
ret_constant = zend_hash_find(&ce->constants_table, constant_name);
|
||||
if (ret_constant == NULL) {
|
||||
if (retval && ce) {
|
||||
if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
|
||||
retval = 0;
|
||||
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
|
||||
zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val);
|
||||
zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name);
|
||||
}
|
||||
} else if (Z_ISREF_P(ret_constant)) {
|
||||
ret_constant = Z_REFVAL_P(ret_constant);
|
||||
}
|
||||
} else if (!ce) {
|
||||
retval = 0;
|
||||
}
|
||||
zend_string_release(class_name);
|
||||
zend_string_free(constant_name);
|
||||
if (ret_constant && Z_CONSTANT_P(ret_constant)) {
|
||||
zval_update_constant_ex(ret_constant, 1, ce TSRMLS_CC);
|
||||
}
|
||||
return ret_constant;
|
||||
efree(class_name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* non-class constant */
|
||||
@@ -411,130 +384,138 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
|
||||
int const_name_len = name_len - prefix_len - 1;
|
||||
const char *constant_name = colon + 1;
|
||||
char *lcname;
|
||||
int lcname_len;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
int found_const = 0;
|
||||
|
||||
lcname_len = prefix_len + 1 + const_name_len;
|
||||
lcname = do_alloca(lcname_len + 1, use_heap);
|
||||
zend_str_tolower_copy(lcname, name, prefix_len);
|
||||
lcname = zend_str_tolower_dup(name, prefix_len);
|
||||
/* Check for namespace constant */
|
||||
|
||||
/* Concatenate lowercase namespace name and constant name */
|
||||
lcname = erealloc(lcname, prefix_len + 1 + const_name_len + 1);
|
||||
lcname[prefix_len] = '\\';
|
||||
memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
|
||||
|
||||
if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) {
|
||||
if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
|
||||
found_const = 1;
|
||||
} else {
|
||||
/* try lowercase */
|
||||
zend_str_tolower(lcname + prefix_len + 1, const_name_len);
|
||||
if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) {
|
||||
if ((c->flags & CONST_CS) != 0) {
|
||||
c = NULL;
|
||||
if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
|
||||
if ((c->flags & CONST_CS) == 0) {
|
||||
found_const = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
if (c) {
|
||||
return &c->value;
|
||||
efree(lcname);
|
||||
if(found_const) {
|
||||
*result = c->value;
|
||||
zval_update_constant_ex(&result, 1, NULL TSRMLS_CC);
|
||||
zval_copy_ctor(result);
|
||||
Z_SET_REFCOUNT_P(result, 1);
|
||||
Z_UNSET_ISREF_P(result);
|
||||
return 1;
|
||||
}
|
||||
/* name requires runtime resolution, need to check non-namespaced name */
|
||||
if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
|
||||
return zend_get_constant_str(constant_name, const_name_len TSRMLS_CC);
|
||||
name = constant_name;
|
||||
name_len = const_name_len;
|
||||
return zend_get_constant(name, name_len, result TSRMLS_CC);
|
||||
}
|
||||
return NULL;
|
||||
retval = 0;
|
||||
finish:
|
||||
if (retval) {
|
||||
zval_update_constant_ex(ret_constant, 1, ce TSRMLS_CC);
|
||||
*result = **ret_constant;
|
||||
zval_copy_ctor(result);
|
||||
INIT_PZVAL(result);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (cname) {
|
||||
return zend_get_constant(cname TSRMLS_CC);
|
||||
} else {
|
||||
return zend_get_constant_str(name, name_len TSRMLS_CC);
|
||||
}
|
||||
return zend_get_constant(name, name_len, result TSRMLS_CC);
|
||||
}
|
||||
|
||||
zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags TSRMLS_DC)
|
||||
zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL) {
|
||||
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
|
||||
key++;
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL ||
|
||||
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
|
||||
(c->flags & CONST_CS) != 0) {
|
||||
if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
|
||||
key++;
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL) {
|
||||
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
|
||||
key++;
|
||||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL ||
|
||||
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
|
||||
(c->flags & CONST_CS) != 0) {
|
||||
|
||||
key--;
|
||||
c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key) TSRMLS_CC);
|
||||
if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
key--;
|
||||
c = zend_get_special_constant(Z_STRVAL_P(key), Z_STRLEN_P(key) TSRMLS_CC);
|
||||
if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
|
||||
{
|
||||
void *ret;
|
||||
zend_constant *copy = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
|
||||
|
||||
memcpy(copy, c, sizeof(zend_constant));
|
||||
ret = zend_hash_add_ptr(ht, key, copy);
|
||||
if (!ret) {
|
||||
pefree(copy, c->flags & CONST_PERSISTENT);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
{
|
||||
zend_string *lowercase_name = NULL;
|
||||
zend_string *name;
|
||||
char *lowercase_name = NULL;
|
||||
char *name;
|
||||
int ret = SUCCESS;
|
||||
ulong chash;
|
||||
|
||||
#if 0
|
||||
printf("Registering constant for module %d\n", c->module_number);
|
||||
#endif
|
||||
|
||||
if (!(c->flags & CONST_CS)) {
|
||||
lowercase_name = zend_string_alloc(c->name->len, c->flags & CONST_PERSISTENT);
|
||||
zend_str_tolower_copy(lowercase_name->val, c->name->val, c->name->len);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name TSRMLS_CC);
|
||||
/* keep in mind that c->name_len already contains the '\0' */
|
||||
lowercase_name = estrndup(c->name, c->name_len-1);
|
||||
zend_str_tolower(lowercase_name, c->name_len-1);
|
||||
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
|
||||
name = lowercase_name;
|
||||
} else {
|
||||
char *slash = strrchr(c->name->val, '\\');
|
||||
char *slash = strrchr(c->name, '\\');
|
||||
if (slash) {
|
||||
lowercase_name = zend_string_init(c->name->val, c->name->len, c->flags & CONST_PERSISTENT);
|
||||
zend_str_tolower(lowercase_name->val, slash - c->name->val);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name TSRMLS_CC);
|
||||
lowercase_name = estrndup(c->name, c->name_len-1);
|
||||
zend_str_tolower(lowercase_name, slash-c->name);
|
||||
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
|
||||
name = lowercase_name;
|
||||
} else {
|
||||
name = c->name;
|
||||
}
|
||||
}
|
||||
chash = str_hash(name, c->name_len-1);
|
||||
|
||||
/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
|
||||
if ((c->name->len == sizeof("__COMPILER_HALT_OFFSET__")-1
|
||||
&& !memcmp(name->val, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
|
||||
|| zend_hash_add_constant(EG(zend_constants), name, c) == NULL) {
|
||||
if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")
|
||||
&& !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
|
||||
|| zend_hash_quick_add(EG(zend_constants), name, c->name_len, chash, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
|
||||
|
||||
/* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
|
||||
if (c->name->val[0] == '\0' && c->name->len > sizeof("\0__COMPILER_HALT_OFFSET__")-1
|
||||
&& memcmp(name->val, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
|
||||
if (c->name[0] == '\0' && c->name_len > sizeof("\0__COMPILER_HALT_OFFSET__")
|
||||
&& memcmp(name, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
|
||||
name++;
|
||||
}
|
||||
zend_error(E_NOTICE,"Constant %s already defined", name->val);
|
||||
zend_string_release(c->name);
|
||||
zend_error(E_NOTICE,"Constant %s already defined", name);
|
||||
str_free(c->name);
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
zval_dtor(&c->value);
|
||||
}
|
||||
ret = FAILURE;
|
||||
}
|
||||
if (lowercase_name) {
|
||||
zend_string_release(lowercase_name);
|
||||
str_efree(lowercase_name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+21
-20
@@ -33,16 +33,17 @@
|
||||
typedef struct _zend_constant {
|
||||
zval value;
|
||||
int flags;
|
||||
zend_string *name;
|
||||
char *name;
|
||||
uint name_len;
|
||||
int module_number;
|
||||
} zend_constant;
|
||||
|
||||
#define REGISTER_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name)-1, (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name)-1, (bval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name)-1, (lval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name)-1, (dval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name)-1, (str), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name)-1, (str), (len), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), module_number TSRMLS_CC)
|
||||
|
||||
#define REGISTER_NS_NULL_CONSTANT(ns, name, flags) zend_register_null_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_NS_BOOL_CONSTANT(ns, name, bval, flags) zend_register_bool_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (bval), (flags), module_number TSRMLS_CC)
|
||||
@@ -51,35 +52,35 @@ typedef struct _zend_constant {
|
||||
#define REGISTER_NS_STRING_CONSTANT(ns, name, str, flags) zend_register_string_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (flags), module_number TSRMLS_CC)
|
||||
#define REGISTER_NS_STRINGL_CONSTANT(ns, name, str, len, flags) zend_register_stringl_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (len), (flags), module_number TSRMLS_CC)
|
||||
|
||||
#define REGISTER_MAIN_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name)-1, (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name)-1, (bval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name)-1, (lval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name)-1, (dval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name)-1, (str), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name)-1, (str), (len), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), 0 TSRMLS_CC)
|
||||
#define REGISTER_MAIN_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), 0 TSRMLS_CC)
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
void clean_module_constants(int module_number TSRMLS_DC);
|
||||
void free_zend_constant(zval *zv);
|
||||
void free_zend_constant(zend_constant *c);
|
||||
int zend_startup_constants(TSRMLS_D);
|
||||
int zend_shutdown_constants(TSRMLS_D);
|
||||
void zend_register_standard_constants(TSRMLS_D);
|
||||
void clean_non_persistent_constants(TSRMLS_D);
|
||||
ZEND_API zval *zend_get_constant(zend_string *name TSRMLS_DC);
|
||||
ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC);
|
||||
ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, zend_ulong flags TSRMLS_DC);
|
||||
ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC);
|
||||
ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC);
|
||||
ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_long_constant(const char *name, uint name_len, zend_long lval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
|
||||
void zend_copy_constants(HashTable *target, HashTable *sourc);
|
||||
zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags TSRMLS_DC);
|
||||
void copy_zend_constant(zend_constant *c);
|
||||
zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_CONSTANT_DTOR free_zend_constant
|
||||
#define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+4
-9
@@ -26,13 +26,8 @@
|
||||
/* PHP DTrace probes {{{ */
|
||||
static inline const char *dtrace_get_executed_filename(TSRMLS_D)
|
||||
{
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
ex = ex->prev_execute_data;
|
||||
}
|
||||
if (ex) {
|
||||
return ex->func->op_array.filename->val;
|
||||
if (EG(current_execute_data) && EG(current_execute_data)->op_array) {
|
||||
return EG(current_execute_data)->op_array->filename;
|
||||
} else {
|
||||
return zend_get_executed_filename(TSRMLS_C);
|
||||
}
|
||||
@@ -86,7 +81,7 @@ ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC)
|
||||
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
|
||||
{
|
||||
int lineno;
|
||||
const char *filename;
|
||||
@@ -99,7 +94,7 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *ret
|
||||
DTRACE_EXECUTE_ENTRY((char *)filename, lineno);
|
||||
}
|
||||
|
||||
execute_internal(execute_data, return_value TSRMLS_CC);
|
||||
execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC);
|
||||
|
||||
if (DTRACE_EXECUTE_RETURN_ENABLED()) {
|
||||
DTRACE_EXECUTE_RETURN((char *)filename, lineno);
|
||||
|
||||
+2
-2
@@ -32,11 +32,11 @@ extern "C" {
|
||||
#ifdef HAVE_DTRACE
|
||||
ZEND_API zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
|
||||
ZEND_API void (*zend_dtrace_execute)(zend_op_array *op_array TSRMLS_DC);
|
||||
ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
|
||||
ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
|
||||
|
||||
ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
|
||||
ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
|
||||
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
|
||||
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
|
||||
#include <zend_dtrace_gen.h>
|
||||
|
||||
#endif /* HAVE_DTRACE */
|
||||
|
||||
+215
-236
@@ -34,29 +34,26 @@ static zend_class_entry *error_exception_ce;
|
||||
static zend_object_handlers default_exception_handlers;
|
||||
ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
|
||||
|
||||
void zend_exception_set_previous(zend_object *exception, zend_object *add_previous TSRMLS_DC)
|
||||
void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
|
||||
{
|
||||
zval tmp, *previous, zv, *pzv;
|
||||
zval *previous;
|
||||
|
||||
if (exception == add_previous || !add_previous || !exception) {
|
||||
return;
|
||||
}
|
||||
ZVAL_OBJ(&tmp, add_previous);
|
||||
if (!instanceof_function(Z_OBJCE(tmp), default_exception_ce TSRMLS_CC)) {
|
||||
if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
|
||||
zend_error(E_ERROR, "Cannot set non exception as previous exception");
|
||||
return;
|
||||
}
|
||||
ZVAL_OBJ(&zv, exception);
|
||||
pzv = &zv;
|
||||
do {
|
||||
previous = zend_read_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
|
||||
while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) {
|
||||
previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
|
||||
if (Z_TYPE_P(previous) == IS_NULL) {
|
||||
zend_update_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, &tmp TSRMLS_CC);
|
||||
GC_REFCOUNT(add_previous)--;
|
||||
zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC);
|
||||
Z_DELREF_P(add_previous);
|
||||
return;
|
||||
}
|
||||
pzv = previous;
|
||||
} while (pzv && Z_OBJ_P(pzv) != add_previous);
|
||||
exception = previous;
|
||||
}
|
||||
}
|
||||
|
||||
void zend_exception_save(TSRMLS_D) /* {{{ */
|
||||
@@ -88,11 +85,12 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#ifdef HAVE_DTRACE
|
||||
if (DTRACE_EXCEPTION_THROWN_ENABLED()) {
|
||||
zend_string *classname;
|
||||
const char *classname;
|
||||
zend_uint name_len;
|
||||
|
||||
if (exception != NULL) {
|
||||
classname = zend_get_object_classname(Z_OBJ_P(exception) TSRMLS_CC);
|
||||
DTRACE_EXCEPTION_THROWN(classname->val);
|
||||
zend_get_object_classname(exception, &classname, &name_len TSRMLS_CC);
|
||||
DTRACE_EXCEPTION_THROWN((char *)classname);
|
||||
} else {
|
||||
DTRACE_EXCEPTION_THROWN(NULL);
|
||||
}
|
||||
@@ -100,9 +98,9 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
|
||||
#endif /* HAVE_DTRACE */
|
||||
|
||||
if (exception != NULL) {
|
||||
zend_object *previous = EG(exception);
|
||||
zend_exception_set_previous(Z_OBJ_P(exception), EG(exception) TSRMLS_CC);
|
||||
EG(exception) = Z_OBJ_P(exception);
|
||||
zval *previous = EG(exception);
|
||||
zend_exception_set_previous(exception, EG(exception) TSRMLS_CC);
|
||||
EG(exception) = exception;
|
||||
if (previous) {
|
||||
return;
|
||||
}
|
||||
@@ -118,8 +116,7 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
|
||||
zend_throw_exception_hook(exception TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!EG(current_execute_data)->func ||
|
||||
!ZEND_USER_CODE(EG(current_execute_data)->func->common.type) ||
|
||||
if (EG(current_execute_data)->opline == NULL ||
|
||||
(EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) {
|
||||
/* no need to rethrow the exception */
|
||||
return;
|
||||
@@ -132,14 +129,13 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
|
||||
ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
if (EG(prev_exception)) {
|
||||
|
||||
OBJ_RELEASE(EG(prev_exception));
|
||||
zval_ptr_dtor(&EG(prev_exception));
|
||||
EG(prev_exception) = NULL;
|
||||
}
|
||||
if (!EG(exception)) {
|
||||
return;
|
||||
}
|
||||
OBJ_RELEASE(EG(exception));
|
||||
zval_ptr_dtor(&EG(exception));
|
||||
EG(exception) = NULL;
|
||||
EG(current_execute_data)->opline = EG(opline_before_exception);
|
||||
#if ZEND_DEBUG
|
||||
@@ -148,35 +144,37 @@ ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval obj;
|
||||
zend_object *object;
|
||||
zval trace;
|
||||
zval *trace;
|
||||
|
||||
Z_OBJ(obj) = object = zend_objects_new(class_type TSRMLS_CC);
|
||||
Z_OBJVAL(obj) = zend_objects_new(&object, class_type TSRMLS_CC);
|
||||
Z_OBJ_HT(obj) = &default_exception_handlers;
|
||||
|
||||
object_properties_init(object, class_type);
|
||||
|
||||
zend_fetch_debug_backtrace(&trace, skip_top_traces, 0, 0 TSRMLS_CC);
|
||||
Z_SET_REFCOUNT(trace, 0);
|
||||
ALLOC_ZVAL(trace);
|
||||
Z_UNSET_ISREF_P(trace);
|
||||
Z_SET_REFCOUNT_P(trace, 0);
|
||||
zend_fetch_debug_backtrace(trace, skip_top_traces, 0, 0 TSRMLS_CC);
|
||||
|
||||
zend_update_property_string(default_exception_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename(TSRMLS_C) TSRMLS_CC);
|
||||
zend_update_property_long(default_exception_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
|
||||
zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, &trace TSRMLS_CC);
|
||||
zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, trace TSRMLS_CC);
|
||||
|
||||
return object;
|
||||
return Z_OBJVAL(obj);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zend_default_exception_new_ex(class_type, 0 TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_error_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_error_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zend_default_exception_new_ex(class_type, 2 TSRMLS_CC);
|
||||
}
|
||||
@@ -195,19 +193,19 @@ ZEND_METHOD(exception, __clone)
|
||||
Exception constructor */
|
||||
ZEND_METHOD(exception, __construct)
|
||||
{
|
||||
zend_string *message = NULL;
|
||||
zend_long code = 0;
|
||||
char *message = NULL;
|
||||
long code = 0;
|
||||
zval *object, *previous = NULL;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
int argc = ZEND_NUM_ARGS(), message_len;
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|SlO!", &message, &code, &previous, default_exception_ce) == FAILURE) {
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO!", &message, &message_len, &code, &previous, default_exception_ce) == FAILURE) {
|
||||
zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])");
|
||||
}
|
||||
|
||||
object = getThis();
|
||||
|
||||
if (message) {
|
||||
zend_update_property_str(default_exception_ce, object, "message", sizeof("message")-1, message TSRMLS_CC);
|
||||
zend_update_property_stringl(default_exception_ce, object, "message", sizeof("message")-1, message, message_len TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (code) {
|
||||
@@ -225,7 +223,7 @@ ZEND_METHOD(exception, __construct)
|
||||
ZEND_METHOD(error_exception, __construct)
|
||||
{
|
||||
char *message = NULL, *filename = NULL;
|
||||
zend_long code = 0, severity = E_ERROR, lineno;
|
||||
long code = 0, severity = E_ERROR, lineno;
|
||||
zval *object, *previous = NULL;
|
||||
int argc = ZEND_NUM_ARGS(), message_len, filename_len;
|
||||
|
||||
@@ -269,7 +267,10 @@ static void _default_exception_get_entry(zval *object, char *name, int name_len,
|
||||
zval *value;
|
||||
|
||||
value = zend_read_property(default_exception_ce, object, name, name_len, 0 TSRMLS_CC);
|
||||
ZVAL_COPY(return_value, value);
|
||||
|
||||
*return_value = *value;
|
||||
zval_copy_ctor(return_value);
|
||||
INIT_PZVAL(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -334,43 +335,45 @@ ZEND_METHOD(error_exception, getSeverity)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ gettraceasstring() macros */
|
||||
#define TRACE_APPEND_CHR(chr) \
|
||||
str = zend_string_realloc(str, str->len + 1, 0); \
|
||||
str->val[str->len - 1] = chr
|
||||
#define TRACE_APPEND_CHR(chr) \
|
||||
*str = (char*)erealloc(*str, *len + 1 + 1); \
|
||||
(*str)[(*len)++] = chr
|
||||
|
||||
#define TRACE_APPEND_STRL(v, l) \
|
||||
{ \
|
||||
str = zend_string_realloc(str, str->len + (l), 0); \
|
||||
memcpy(str->val + str->len - (l), (v), (l)); \
|
||||
#define TRACE_APPEND_STRL(val, vallen) \
|
||||
{ \
|
||||
int l = vallen; \
|
||||
*str = (char*)erealloc(*str, *len + l + 1); \
|
||||
memcpy((*str) + *len, val, l); \
|
||||
*len += l; \
|
||||
}
|
||||
|
||||
#define TRACE_APPEND_STR(v) \
|
||||
TRACE_APPEND_STRL((v), sizeof((v))-1)
|
||||
#define TRACE_APPEND_STR(val) \
|
||||
TRACE_APPEND_STRL(val, sizeof(val)-1)
|
||||
|
||||
#define TRACE_APPEND_KEY(key) do { \
|
||||
tmp = zend_hash_str_find(ht, key, sizeof(key)-1); \
|
||||
if (tmp) { \
|
||||
if (Z_TYPE_P(tmp) != IS_STRING) { \
|
||||
zend_error(E_WARNING, "Value for %s is no string", key); \
|
||||
TRACE_APPEND_STR("[unknown]"); \
|
||||
} else { \
|
||||
TRACE_APPEND_STRL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define TRACE_APPEND_KEY(key) \
|
||||
if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
|
||||
if (Z_TYPE_PP(tmp) != IS_STRING) { \
|
||||
zend_error(E_WARNING, "Value for %s is no string", key); \
|
||||
TRACE_APPEND_STR("[unknown]"); \
|
||||
} else { \
|
||||
TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define TRACE_ARG_APPEND(vallen) do { \
|
||||
int len = str->len; \
|
||||
str = zend_string_realloc(str, len + vallen, 0); \
|
||||
memmove(str->val + len - l_added + 1 + vallen, str->val + len - l_added + 1, l_added); \
|
||||
} while (0)
|
||||
#define TRACE_ARG_APPEND(vallen) \
|
||||
*str = (char*)erealloc(*str, *len + 1 + vallen); \
|
||||
memmove((*str) + *len - l_added + 1 + vallen, (*str) + *len - l_added + 1, l_added);
|
||||
|
||||
/* }}} */
|
||||
|
||||
static void _build_trace_args(zval *arg, zend_string **str_ptr TSRMLS_DC) /* {{{ */
|
||||
static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
|
||||
{
|
||||
zend_string *str = *str_ptr;
|
||||
char **str;
|
||||
int *len;
|
||||
|
||||
str = va_arg(args, char**);
|
||||
len = va_arg(args, int*);
|
||||
|
||||
/* the trivial way would be to do:
|
||||
* convert_to_string_ex(arg);
|
||||
@@ -378,49 +381,48 @@ static void _build_trace_args(zval *arg, zend_string **str_ptr TSRMLS_DC) /* {{{
|
||||
* but that could cause some E_NOTICE and also damn long lines.
|
||||
*/
|
||||
|
||||
ZVAL_DEREF(arg);
|
||||
switch (Z_TYPE_P(arg)) {
|
||||
switch (Z_TYPE_PP(arg)) {
|
||||
case IS_NULL:
|
||||
TRACE_APPEND_STR("NULL, ");
|
||||
break;
|
||||
case IS_STRING: {
|
||||
int l_added;
|
||||
TRACE_APPEND_CHR('\'');
|
||||
if (Z_STRLEN_P(arg) > 15) {
|
||||
TRACE_APPEND_STRL(Z_STRVAL_P(arg), 15);
|
||||
if (Z_STRLEN_PP(arg) > 15) {
|
||||
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15);
|
||||
TRACE_APPEND_STR("...', ");
|
||||
l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
|
||||
} else {
|
||||
l_added = Z_STRLEN_P(arg);
|
||||
TRACE_APPEND_STRL(Z_STRVAL_P(arg), l_added);
|
||||
l_added = Z_STRLEN_PP(arg);
|
||||
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added);
|
||||
TRACE_APPEND_STR("', ");
|
||||
l_added += 3 + 1;
|
||||
}
|
||||
while (--l_added) {
|
||||
unsigned char chr = str->val[str->len - l_added];
|
||||
unsigned char chr = (*str)[*len - l_added];
|
||||
if (chr < 32 || chr == '\\' || chr > 126) {
|
||||
str->val[str->len - l_added] = '\\';
|
||||
(*str)[*len - l_added] = '\\';
|
||||
|
||||
switch (chr) {
|
||||
case '\n':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 'n';
|
||||
(*str)[++(*len) - l_added] = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 'r';
|
||||
(*str)[++(*len) - l_added] = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 't';
|
||||
(*str)[++(*len) - l_added] = 't';
|
||||
break;
|
||||
case '\f':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 'f';
|
||||
(*str)[++(*len) - l_added] = 'f';
|
||||
break;
|
||||
case '\v':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 'v';
|
||||
(*str)[++(*len) - l_added] = 'v';
|
||||
break;
|
||||
#ifndef PHP_WIN32
|
||||
case '\e':
|
||||
@@ -428,55 +430,51 @@ static void _build_trace_args(zval *arg, zend_string **str_ptr TSRMLS_DC) /* {{{
|
||||
case VK_ESCAPE:
|
||||
#endif
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = 'e';
|
||||
(*str)[++(*len) - l_added] = 'e';
|
||||
break;
|
||||
case '\\':
|
||||
TRACE_ARG_APPEND(1);
|
||||
str->val[str->len - l_added] = '\\';
|
||||
(*str)[++(*len) - l_added] = '\\';
|
||||
break;
|
||||
default:
|
||||
TRACE_ARG_APPEND(3);
|
||||
str->val[str->len - l_added - 2] = 'x';
|
||||
(*str)[*len - l_added + 1] = 'x';
|
||||
if ((chr >> 4) < 10) {
|
||||
str->val[str->len - l_added - 1] = (chr >> 4) + '0';
|
||||
(*str)[*len - l_added + 2] = (chr >> 4) + '0';
|
||||
} else {
|
||||
str->val[str->len - l_added - 1] = (chr >> 4) + 'A' - 10;
|
||||
(*str)[*len - l_added + 2] = (chr >> 4) + 'A' - 10;
|
||||
}
|
||||
if (chr % 16 < 10) {
|
||||
str->val[str->len - l_added] = chr % 16 + '0';
|
||||
(*str)[*len - l_added + 3] = chr % 16 + '0';
|
||||
} else {
|
||||
str->val[str->len - l_added] = chr % 16 + 'A' - 10;
|
||||
(*str)[*len - l_added + 3] = chr % 16 + 'A' - 10;
|
||||
}
|
||||
*len += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_FALSE:
|
||||
TRACE_APPEND_STR("false, ");
|
||||
case IS_BOOL:
|
||||
if (Z_LVAL_PP(arg)) {
|
||||
TRACE_APPEND_STR("true, ");
|
||||
} else {
|
||||
TRACE_APPEND_STR("false, ");
|
||||
}
|
||||
break;
|
||||
case IS_TRUE:
|
||||
TRACE_APPEND_STR("true, ");
|
||||
break;
|
||||
case IS_RESOURCE: {
|
||||
zend_long lval = Z_RES_HANDLE_P(arg);
|
||||
char s_tmp[MAX_LENGTH_OF_LONG + 1];
|
||||
int l_tmp = zend_sprintf(s_tmp, ZEND_LONG_FMT, lval); /* SAFE */
|
||||
case IS_RESOURCE:
|
||||
TRACE_APPEND_STR("Resource id #");
|
||||
TRACE_APPEND_STRL(s_tmp, l_tmp);
|
||||
TRACE_APPEND_STR(", ");
|
||||
break;
|
||||
}
|
||||
/* break; */
|
||||
case IS_LONG: {
|
||||
zend_long lval = Z_LVAL_P(arg);
|
||||
long lval = Z_LVAL_PP(arg);
|
||||
char s_tmp[MAX_LENGTH_OF_LONG + 1];
|
||||
int l_tmp = zend_sprintf(s_tmp, ZEND_LONG_FMT, lval); /* SAFE */
|
||||
int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */
|
||||
TRACE_APPEND_STRL(s_tmp, l_tmp);
|
||||
TRACE_APPEND_STR(", ");
|
||||
break;
|
||||
}
|
||||
case IS_DOUBLE: {
|
||||
double dval = Z_DVAL_P(arg);
|
||||
double dval = Z_DVAL_PP(arg);
|
||||
char *s_tmp;
|
||||
int l_tmp;
|
||||
|
||||
@@ -492,52 +490,58 @@ static void _build_trace_args(zval *arg, zend_string **str_ptr TSRMLS_DC) /* {{{
|
||||
TRACE_APPEND_STR("Array, ");
|
||||
break;
|
||||
case IS_OBJECT: {
|
||||
zend_string *class_name;
|
||||
const char *class_name;
|
||||
zend_uint class_name_len;
|
||||
int dup;
|
||||
|
||||
TRACE_APPEND_STR("Object(");
|
||||
|
||||
class_name = zend_get_object_classname(Z_OBJ_P(arg) TSRMLS_CC);
|
||||
dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC);
|
||||
|
||||
TRACE_APPEND_STRL(class_name, class_name_len);
|
||||
if(!dup) {
|
||||
efree((char*)class_name);
|
||||
}
|
||||
|
||||
TRACE_APPEND_STRL(class_name->val, class_name->len);
|
||||
TRACE_APPEND_STR("), ");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*str_ptr = str;
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _build_trace_string(zval *frame, zend_ulong index, zend_string **str_ptr, int *num TSRMLS_DC) /* {{{ */
|
||||
static int _build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
|
||||
{
|
||||
char *s_tmp;
|
||||
int len;
|
||||
char *s_tmp, **str;
|
||||
int *len, *num;
|
||||
long line;
|
||||
HashTable *ht;
|
||||
zval *file, *tmp;
|
||||
zend_string *str = *str_ptr;
|
||||
HashTable *ht = Z_ARRVAL_PP(frame);
|
||||
zval **file, **tmp;
|
||||
|
||||
if (Z_TYPE_P(frame) != IS_ARRAY) {
|
||||
zend_error(E_WARNING, "Expected array for frame %pu", index);
|
||||
return;
|
||||
if (Z_TYPE_PP(frame) != IS_ARRAY) {
|
||||
zend_error(E_WARNING, "Expected array for frame %lu", hash_key->h);
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
||||
ht = Z_ARRVAL_P(frame);
|
||||
str = va_arg(args, char**);
|
||||
len = va_arg(args, int*);
|
||||
num = va_arg(args, int*);
|
||||
|
||||
s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1);
|
||||
len = sprintf(s_tmp, "#%d ", (*num)++);
|
||||
TRACE_APPEND_STRL(s_tmp, len);
|
||||
sprintf(s_tmp, "#%d ", (*num)++);
|
||||
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
|
||||
efree(s_tmp);
|
||||
file = zend_hash_str_find(ht, "file", sizeof("file")-1);
|
||||
if (file) {
|
||||
if (Z_TYPE_P(file) != IS_STRING) {
|
||||
if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) {
|
||||
if (Z_TYPE_PP(file) != IS_STRING) {
|
||||
zend_error(E_WARNING, "Function name is no string");
|
||||
TRACE_APPEND_STR("[unknown function]");
|
||||
} else{
|
||||
tmp = zend_hash_str_find(ht, "line", sizeof("line")-1);
|
||||
if (tmp) {
|
||||
if (Z_TYPE_P(tmp) == IS_LONG) {
|
||||
line = Z_LVAL_P(tmp);
|
||||
if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) {
|
||||
if (Z_TYPE_PP(tmp) == IS_LONG) {
|
||||
line = Z_LVAL_PP(tmp);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Line is no long");
|
||||
line = 0;
|
||||
@@ -545,9 +549,9 @@ static void _build_trace_string(zval *frame, zend_ulong index, zend_string **str
|
||||
} else {
|
||||
line = 0;
|
||||
}
|
||||
s_tmp = emalloc(Z_STRLEN_P(file) + MAX_LENGTH_OF_LONG + 4 + 1);
|
||||
len = sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_P(file), line);
|
||||
TRACE_APPEND_STRL(s_tmp, len);
|
||||
s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1);
|
||||
sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line);
|
||||
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
|
||||
efree(s_tmp);
|
||||
}
|
||||
} else {
|
||||
@@ -557,25 +561,19 @@ static void _build_trace_string(zval *frame, zend_ulong index, zend_string **str
|
||||
TRACE_APPEND_KEY("type");
|
||||
TRACE_APPEND_KEY("function");
|
||||
TRACE_APPEND_CHR('(');
|
||||
tmp = zend_hash_str_find(ht, "args", sizeof("args")-1);
|
||||
if (tmp) {
|
||||
if (Z_TYPE_P(tmp) == IS_ARRAY) {
|
||||
int last_len = str->len;
|
||||
zval *arg;
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmp), arg) {
|
||||
_build_trace_args(arg, &str TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (last_len != str->len) {
|
||||
str->len -= 2; /* remove last ', ' */
|
||||
if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) {
|
||||
if (Z_TYPE_PP(tmp) == IS_ARRAY) {
|
||||
int last_len = *len;
|
||||
zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)_build_trace_args, 2, str, len);
|
||||
if (last_len != *len) {
|
||||
*len -= 2; /* remove last ', ' */
|
||||
}
|
||||
} else {
|
||||
zend_error(E_WARNING, "args element is no array");
|
||||
}
|
||||
}
|
||||
TRACE_APPEND_STR(")\n");
|
||||
*str_ptr = str;
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -583,27 +581,25 @@ static void _build_trace_string(zval *frame, zend_ulong index, zend_string **str
|
||||
Obtain the backtrace for the exception as a string (instead of an array) */
|
||||
ZEND_METHOD(exception, getTraceAsString)
|
||||
{
|
||||
zval *trace, *frame;
|
||||
zend_ulong index;
|
||||
zend_string *str, *key;
|
||||
int num = 0, len;
|
||||
char s_tmp[MAX_LENGTH_OF_LONG + 7 + 1 + 1];
|
||||
zval *trace;
|
||||
char *res, **str, *s_tmp;
|
||||
int res_len = 0, *len = &res_len, num = 0;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
str = zend_string_alloc(0, 0);
|
||||
res = estrdup("");
|
||||
str = &res;
|
||||
|
||||
trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
|
||||
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(trace), index, key, frame) {
|
||||
_build_trace_string(frame, index, &str, &num TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)_build_trace_string, 3, str, len, &num);
|
||||
|
||||
len = sprintf(s_tmp, "#%d {main}", num);
|
||||
TRACE_APPEND_STRL(s_tmp, len);
|
||||
s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1);
|
||||
sprintf(s_tmp, "#%d {main}", num);
|
||||
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
|
||||
efree(s_tmp);
|
||||
|
||||
str->val[str->len] = '\0';
|
||||
|
||||
RETURN_NEW_STR(str);
|
||||
res[res_len] = '\0';
|
||||
RETURN_STRINGL(res, res_len, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -617,7 +613,7 @@ ZEND_METHOD(exception, getPrevious)
|
||||
|
||||
previous = zend_read_property(default_exception_ce, getThis(), "previous", sizeof("previous")-1, 1 TSRMLS_CC);
|
||||
RETURN_ZVAL(previous, 1, 0);
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
|
||||
{
|
||||
@@ -631,33 +627,22 @@ int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ *
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
zend_string *zend_strpprintf(int max_len, const char *format, ...) /* {{{ */
|
||||
{
|
||||
va_list arg;
|
||||
zend_string *str;
|
||||
|
||||
va_start(arg, format);
|
||||
str = zend_vstrpprintf(max_len, format, arg);
|
||||
va_end(arg);
|
||||
return str;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string Exception::__toString()
|
||||
Obtain the string representation of the Exception object */
|
||||
ZEND_METHOD(exception, __toString)
|
||||
{
|
||||
zval message, file, line, trace, *exception;
|
||||
zend_string *str, *prev_str;
|
||||
zval message, file, line, *trace, *exception;
|
||||
char *str, *prev_str;
|
||||
int len = 0;
|
||||
zend_fcall_info fci;
|
||||
zval fname;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
str = STR_EMPTY_ALLOC();
|
||||
str = estrndup("", 0);
|
||||
|
||||
exception = getThis();
|
||||
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1);
|
||||
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1);
|
||||
|
||||
while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
|
||||
prev_str = str;
|
||||
@@ -665,55 +650,57 @@ ZEND_METHOD(exception, __toString)
|
||||
_default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC);
|
||||
_default_exception_get_entry(exception, "line", sizeof("line")-1, &line TSRMLS_CC);
|
||||
|
||||
convert_to_string_ex(&message);
|
||||
convert_to_string_ex(&file);
|
||||
convert_to_long_ex(&line);
|
||||
convert_to_string(&message);
|
||||
convert_to_string(&file);
|
||||
convert_to_long(&line);
|
||||
|
||||
fci.size = sizeof(fci);
|
||||
fci.function_table = &Z_OBJCE_P(exception)->function_table;
|
||||
ZVAL_COPY_VALUE(&fci.function_name, &fname);
|
||||
fci.function_name = &fname;
|
||||
fci.symbol_table = NULL;
|
||||
fci.object = Z_OBJ_P(exception);
|
||||
fci.retval = &trace;
|
||||
fci.object_ptr = exception;
|
||||
fci.retval_ptr_ptr = &trace;
|
||||
fci.param_count = 0;
|
||||
fci.params = NULL;
|
||||
fci.no_separation = 1;
|
||||
|
||||
zend_call_function(&fci, NULL TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(trace) != IS_STRING) {
|
||||
if (Z_TYPE_P(trace) != IS_STRING) {
|
||||
zval_ptr_dtor(&trace);
|
||||
ZVAL_UNDEF(&trace);
|
||||
trace = NULL;
|
||||
}
|
||||
|
||||
if (Z_STRLEN(message) > 0) {
|
||||
str = zend_strpprintf(0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
|
||||
Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
|
||||
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
|
||||
prev_str->len ? "\n\nNext " : "", prev_str->val);
|
||||
len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
|
||||
Z_OBJCE_P(exception)->name, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
|
||||
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
|
||||
len ? "\n\nNext " : "", prev_str);
|
||||
} else {
|
||||
str = zend_strpprintf(0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
|
||||
Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
|
||||
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
|
||||
prev_str->len ? "\n\nNext " : "", prev_str->val);
|
||||
len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
|
||||
Z_OBJCE_P(exception)->name, Z_STRVAL(file), Z_LVAL(line),
|
||||
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
|
||||
len ? "\n\nNext " : "", prev_str);
|
||||
}
|
||||
zend_string_release(prev_str);
|
||||
efree(prev_str);
|
||||
zval_dtor(&message);
|
||||
zval_dtor(&file);
|
||||
zval_dtor(&line);
|
||||
|
||||
exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(&trace);
|
||||
if (trace) {
|
||||
zval_ptr_dtor(&trace);
|
||||
}
|
||||
|
||||
}
|
||||
zval_dtor(&fname);
|
||||
|
||||
/* We store the result in the private property string so we can access
|
||||
* the result in uncaught exception handlers without memleaks. */
|
||||
zend_update_property_str(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
|
||||
zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
|
||||
|
||||
RETURN_STR(str);
|
||||
RETURN_STRINGL(str, len, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -782,7 +769,7 @@ void zend_register_default_exception(TSRMLS_D) /* {{{ */
|
||||
zend_declare_property_null(default_exception_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "ErrorException", error_exception_functions);
|
||||
error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce TSRMLS_CC);
|
||||
error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce, NULL TSRMLS_CC);
|
||||
error_exception_ce->create_object = zend_error_exception_new;
|
||||
zend_declare_property_long(error_exception_ce, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED TSRMLS_CC);
|
||||
}
|
||||
@@ -800,10 +787,11 @@ ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
|
||||
ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval ex;
|
||||
zval *ex;
|
||||
|
||||
MAKE_STD_ZVAL(ex);
|
||||
if (exception_ce) {
|
||||
if (!instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Exceptions must be derived from the Exception base class");
|
||||
@@ -812,43 +800,41 @@ ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const
|
||||
} else {
|
||||
exception_ce = default_exception_ce;
|
||||
}
|
||||
object_init_ex(&ex, exception_ce);
|
||||
object_init_ex(ex, exception_ce);
|
||||
|
||||
|
||||
if (message) {
|
||||
zend_update_property_string(default_exception_ce, &ex, "message", sizeof("message")-1, message TSRMLS_CC);
|
||||
zend_update_property_string(default_exception_ce, ex, "message", sizeof("message")-1, message TSRMLS_CC);
|
||||
}
|
||||
if (code) {
|
||||
zend_update_property_long(default_exception_ce, &ex, "code", sizeof("code")-1, code TSRMLS_CC);
|
||||
zend_update_property_long(default_exception_ce, ex, "code", sizeof("code")-1, code TSRMLS_CC);
|
||||
}
|
||||
|
||||
zend_throw_exception_internal(&ex TSRMLS_CC);
|
||||
return Z_OBJ(ex);
|
||||
zend_throw_exception_internal(ex TSRMLS_CC);
|
||||
return ex;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
|
||||
ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
|
||||
{
|
||||
va_list arg;
|
||||
char *message;
|
||||
zend_object *obj;
|
||||
zval *zexception;
|
||||
|
||||
va_start(arg, format);
|
||||
zend_vspprintf(&message, 0, format, arg);
|
||||
va_end(arg);
|
||||
obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
|
||||
zexception = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
|
||||
efree(message);
|
||||
return obj;
|
||||
return zexception;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
|
||||
ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval ex;
|
||||
zend_object *obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
|
||||
ZVAL_OBJ(&ex, obj);
|
||||
zend_update_property_long(default_exception_ce, &ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
|
||||
return obj;
|
||||
zval *ex = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
|
||||
zend_update_property_long(default_exception_ce, ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
|
||||
return ex;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -863,58 +849,51 @@ static void zend_error_va(int type, const char *file, uint lineno, const char *f
|
||||
/* }}} */
|
||||
|
||||
/* This function doesn't return if it uses E_ERROR */
|
||||
ZEND_API void zend_exception_error(zend_object *ex, int severity TSRMLS_DC) /* {{{ */
|
||||
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval exception;
|
||||
zend_class_entry *ce_exception;
|
||||
|
||||
ZVAL_OBJ(&exception, ex);
|
||||
ce_exception = Z_OBJCE(exception);
|
||||
zend_class_entry *ce_exception = Z_OBJCE_P(exception);
|
||||
if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
|
||||
zval tmp, *str, *file, *line;
|
||||
zval *str, *file, *line;
|
||||
|
||||
EG(exception) = NULL;
|
||||
|
||||
zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &tmp);
|
||||
zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str);
|
||||
if (!EG(exception)) {
|
||||
if (Z_TYPE(tmp) != IS_STRING) {
|
||||
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name->val);
|
||||
if (Z_TYPE_P(str) != IS_STRING) {
|
||||
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name);
|
||||
} else {
|
||||
zend_update_property_string(default_exception_ce, &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp) TSRMLS_CC);
|
||||
zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&tmp);
|
||||
zval_ptr_dtor(&str);
|
||||
|
||||
if (EG(exception)) {
|
||||
zval zv;
|
||||
|
||||
ZVAL_OBJ(&zv, EG(exception));
|
||||
/* do the best we can to inform about the inner exception */
|
||||
if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
|
||||
file = zend_read_property(default_exception_ce, &zv, "file", sizeof("file")-1, 1 TSRMLS_CC);
|
||||
line = zend_read_property(default_exception_ce, &zv, "line", sizeof("line")-1, 1 TSRMLS_CC);
|
||||
file = zend_read_property(default_exception_ce, EG(exception), "file", sizeof("file")-1, 1 TSRMLS_CC);
|
||||
line = zend_read_property(default_exception_ce, EG(exception), "line", sizeof("line")-1, 1 TSRMLS_CC);
|
||||
|
||||
convert_to_string_ex(file);
|
||||
convert_to_string(file);
|
||||
file = (Z_STRLEN_P(file) > 0) ? file : NULL;
|
||||
line = (Z_TYPE_P(line) == IS_LONG) ? line : NULL;
|
||||
} else {
|
||||
file = NULL;
|
||||
line = NULL;
|
||||
}
|
||||
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE(zv)->name->val, ce_exception->name->val);
|
||||
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name);
|
||||
}
|
||||
|
||||
str = zend_read_property(default_exception_ce, &exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
|
||||
file = zend_read_property(default_exception_ce, &exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
|
||||
line = zend_read_property(default_exception_ce, &exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
|
||||
str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
|
||||
file = zend_read_property(default_exception_ce, exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
|
||||
line = zend_read_property(default_exception_ce, exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
|
||||
|
||||
convert_to_string_ex(str);
|
||||
convert_to_string_ex(file);
|
||||
convert_to_long_ex(line);
|
||||
convert_to_string(str);
|
||||
convert_to_string(file);
|
||||
convert_to_long(line);
|
||||
|
||||
zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %s\n thrown", Z_STRVAL_P(str));
|
||||
} else {
|
||||
zend_error(severity, "Uncaught exception '%s'", ce_exception->name->val);
|
||||
zend_error(severity, "Uncaught exception '%s'", ce_exception->name);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous TSRMLS_DC);
|
||||
ZEND_API void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC);
|
||||
ZEND_API void zend_exception_save(TSRMLS_D);
|
||||
ZEND_API void zend_exception_restore(TSRMLS_D);
|
||||
|
||||
@@ -40,21 +40,20 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
|
||||
|
||||
/* exception_ce NULL or zend_exception_get_default() or a derived class
|
||||
* message NULL or the message of the exception */
|
||||
ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
|
||||
ZEND_API zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
|
||||
ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
|
||||
ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
|
||||
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
|
||||
ZEND_API void zend_clear_exception(TSRMLS_D);
|
||||
|
||||
ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
|
||||
ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
|
||||
|
||||
extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
|
||||
|
||||
/* show an exception using zend_error(severity,...), severity should be E_ERROR */
|
||||
ZEND_API void zend_exception_error(zend_object *exception, int severity TSRMLS_DC);
|
||||
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC);
|
||||
|
||||
/* do not export, in php it's available thru spprintf directly */
|
||||
int zend_spprintf(char **message, int max_len, const char *format, ...);
|
||||
zend_string *zend_strpprintf(int max_len, const char *format, ...);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
|
||||
+1195
-1239
File diff suppressed because it is too large.
Load diff
+210
-150
@@ -27,71 +27,92 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_variables.h"
|
||||
|
||||
typedef union _temp_variable {
|
||||
zval tmp_var;
|
||||
struct {
|
||||
zval **ptr_ptr;
|
||||
zval *ptr;
|
||||
zend_bool fcall_returned_reference;
|
||||
} var;
|
||||
struct {
|
||||
zval **ptr_ptr; /* shared with var.ptr_ptr */
|
||||
zval *str;
|
||||
zend_uint offset;
|
||||
} str_offset;
|
||||
struct {
|
||||
zval **ptr_ptr; /* shared with var.ptr_ptr */
|
||||
zval *ptr; /* shared with var.ptr */
|
||||
HashPointer fe_pos;
|
||||
} fe;
|
||||
zend_class_entry *class_entry;
|
||||
} temp_variable;
|
||||
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
struct _zend_fcall_info;
|
||||
ZEND_API extern void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
|
||||
ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
|
||||
ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
|
||||
|
||||
void init_executor(TSRMLS_D);
|
||||
void shutdown_executor(TSRMLS_D);
|
||||
void shutdown_destructors(TSRMLS_D);
|
||||
ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC);
|
||||
ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC);
|
||||
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC);
|
||||
ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC);
|
||||
ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC);
|
||||
ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
|
||||
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
|
||||
ZEND_API int zend_is_true(zval *op TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload TSRMLS_DC);
|
||||
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
|
||||
ZEND_API int zend_is_true(zval *op);
|
||||
ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
|
||||
ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
|
||||
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
|
||||
ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
|
||||
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
|
||||
ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
|
||||
|
||||
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, zend_ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uint32_t arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind, zval *arg TSRMLS_DC);
|
||||
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC);
|
||||
|
||||
static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC)
|
||||
{
|
||||
if (Z_REFCOUNTED_P(zval_ptr)) {
|
||||
if (!Z_DELREF_P(zval_ptr)) {
|
||||
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
|
||||
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_CC);
|
||||
} else {
|
||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr);
|
||||
if (!Z_DELREF_P(zval_ptr)) {
|
||||
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
|
||||
GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr);
|
||||
zval_dtor(zval_ptr);
|
||||
efree_rel(zval_ptr);
|
||||
} else {
|
||||
if (Z_REFCOUNT_P(zval_ptr) == 1) {
|
||||
Z_UNSET_ISREF_P(zval_ptr);
|
||||
}
|
||||
|
||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void i_zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC)
|
||||
{
|
||||
if (Z_REFCOUNTED_P(zval_ptr)) {
|
||||
if (!Z_DELREF_P(zval_ptr)) {
|
||||
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
|
||||
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_CC);
|
||||
if (!Z_DELREF_P(zval_ptr)) {
|
||||
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
|
||||
GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr);
|
||||
zval_dtor(zval_ptr);
|
||||
efree_rel(zval_ptr);
|
||||
} else {
|
||||
if (Z_REFCOUNT_P(zval_ptr) == 1) {
|
||||
Z_UNSET_ISREF_P(zval_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
|
||||
static zend_always_inline int i_zend_is_true(zval *op)
|
||||
{
|
||||
int result;
|
||||
|
||||
again:
|
||||
switch (Z_TYPE_P(op)) {
|
||||
case IS_UNDEF:
|
||||
case IS_NULL:
|
||||
case IS_FALSE:
|
||||
result = 0;
|
||||
break;
|
||||
case IS_TRUE:
|
||||
result = 1;
|
||||
break;
|
||||
case IS_LONG:
|
||||
result = (Z_LVAL_P(op)?1:0);
|
||||
break;
|
||||
case IS_BOOL:
|
||||
case IS_RESOURCE:
|
||||
result = (Z_RES_HANDLE_P(op)?1:0);
|
||||
result = (Z_LVAL_P(op)?1:0);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
result = (Z_DVAL_P(op) ? 1 : 0);
|
||||
@@ -108,32 +129,28 @@ again:
|
||||
result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
if (IS_ZEND_STD_OBJECT(*op)) {
|
||||
if(IS_ZEND_STD_OBJECT(*op)) {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (Z_OBJ_HT_P(op)->cast_object) {
|
||||
zval tmp;
|
||||
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL TSRMLS_CC) == SUCCESS) {
|
||||
result = Z_TYPE(tmp) == IS_TRUE;
|
||||
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
|
||||
result = Z_LVAL(tmp);
|
||||
break;
|
||||
}
|
||||
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
|
||||
} else if (Z_OBJ_HT_P(op)->get) {
|
||||
zval rv;
|
||||
zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv TSRMLS_CC);
|
||||
if (Z_TYPE_P(tmp) != IS_OBJECT) {
|
||||
zval *tmp = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
|
||||
if(Z_TYPE_P(tmp) != IS_OBJECT) {
|
||||
/* for safety - avoid loop */
|
||||
convert_to_boolean(tmp);
|
||||
result = Z_TYPE_P(tmp) == IS_TRUE;
|
||||
zval_ptr_dtor(tmp);
|
||||
result = Z_LVAL_P(tmp);
|
||||
zval_ptr_dtor(&tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = 1;
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
op = Z_REFVAL_P(op);
|
||||
goto again;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
@@ -141,40 +158,36 @@ again:
|
||||
return result;
|
||||
}
|
||||
|
||||
ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_ex(zval *pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC);
|
||||
|
||||
/* dedicated Zend executor functions - do not use! */
|
||||
#define ZEND_VM_STACK_PAGE_SIZE (16 * 1024) /* should be a power of 2 */
|
||||
#define ZEND_VM_STACK_PAGE_SIZE ((16 * 1024) - 16)
|
||||
|
||||
struct _zend_vm_stack {
|
||||
zval *top;
|
||||
zval *end;
|
||||
void **top;
|
||||
void **end;
|
||||
zend_vm_stack prev;
|
||||
};
|
||||
|
||||
#define ZEND_VM_STACK_HEADER_SLOT \
|
||||
((ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))
|
||||
|
||||
#define ZEND_VM_STACK_ELEMETS(stack) \
|
||||
(((zval*)(stack)) + ZEND_VM_STACK_HEADER_SLOT)
|
||||
((void**)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack))))
|
||||
|
||||
#define ZEND_VM_STACK_GROW_IF_NEEDED(count) \
|
||||
do { \
|
||||
if (UNEXPECTED(((count) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) > \
|
||||
(size_t)(((char*)EG(argument_stack)->end) - \
|
||||
((char*)EG(argument_stack)->top)))) { \
|
||||
zend_vm_stack_extend((count) TSRMLS_CC); \
|
||||
} \
|
||||
#define ZEND_VM_STACK_GROW_IF_NEEDED(count) \
|
||||
do { \
|
||||
if (UNEXPECTED((count) > \
|
||||
EG(argument_stack)->end - EG(argument_stack)->top)) { \
|
||||
zend_vm_stack_extend((count) TSRMLS_CC); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static zend_always_inline zend_vm_stack zend_vm_stack_new_page(int count) {
|
||||
zend_vm_stack page = (zend_vm_stack)emalloc(count * ZEND_MM_ALIGNED_SIZE(sizeof(zval)));
|
||||
zend_vm_stack page = (zend_vm_stack)emalloc(ZEND_MM_ALIGNED_SIZE(sizeof(*page)) + sizeof(void*) * count);
|
||||
|
||||
page->top = ZEND_VM_STACK_ELEMETS(page);
|
||||
page->end = (zval*)page + count;
|
||||
page->end = page->top + count;
|
||||
page->prev = NULL;
|
||||
return page;
|
||||
}
|
||||
@@ -182,7 +195,6 @@ static zend_always_inline zend_vm_stack zend_vm_stack_new_page(int count) {
|
||||
static zend_always_inline void zend_vm_stack_init(TSRMLS_D)
|
||||
{
|
||||
EG(argument_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE);
|
||||
EG(argument_stack)->top++;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_destroy(TSRMLS_D)
|
||||
@@ -198,77 +210,141 @@ static zend_always_inline void zend_vm_stack_destroy(TSRMLS_D)
|
||||
|
||||
static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
|
||||
{
|
||||
int size = count * ZEND_MM_ALIGNED_SIZE(sizeof(zval));
|
||||
zend_vm_stack p = zend_vm_stack_new_page(
|
||||
(size >= (ZEND_VM_STACK_PAGE_SIZE - ZEND_VM_STACK_HEADER_SLOT) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) ?
|
||||
(size + ((ZEND_VM_STACK_HEADER_SLOT + ZEND_VM_STACK_PAGE_SIZE) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) - 1) &
|
||||
~((ZEND_VM_STACK_PAGE_SIZE * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) - 1) :
|
||||
ZEND_VM_STACK_PAGE_SIZE);
|
||||
zend_vm_stack p = zend_vm_stack_new_page(count >= ZEND_VM_STACK_PAGE_SIZE ? count : ZEND_VM_STACK_PAGE_SIZE);
|
||||
p->prev = EG(argument_stack);
|
||||
EG(argument_stack) = p;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, uint32_t num_args, zend_uchar flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||
static zend_always_inline void **zend_vm_stack_top(TSRMLS_D)
|
||||
{
|
||||
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
||||
zend_execute_data *call;
|
||||
|
||||
if (ZEND_USER_CODE(func->type)) {
|
||||
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
|
||||
return EG(argument_stack)->top;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
|
||||
{
|
||||
*(EG(argument_stack)->top++) = ptr;
|
||||
}
|
||||
|
||||
static zend_always_inline void *zend_vm_stack_pop(TSRMLS_D)
|
||||
{
|
||||
void *el = *(--EG(argument_stack)->top);
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
static zend_always_inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
size = (size + (sizeof(void*) - 1)) / sizeof(void*);
|
||||
|
||||
/* the following comparison must be optimized out at compile time */
|
||||
if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
|
||||
int extra = (ZEND_MM_ALIGNMENT - ((zend_uintptr_t)EG(argument_stack)->top & (ZEND_MM_ALIGNMENT - 1))) / sizeof(void*);
|
||||
|
||||
if (UNEXPECTED(size + extra + ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*) >
|
||||
(zend_uintptr_t)(EG(argument_stack)->end - EG(argument_stack)->top))) {
|
||||
zend_vm_stack_extend(size TSRMLS_CC);
|
||||
} else {
|
||||
void **old_top = EG(argument_stack)->top;
|
||||
|
||||
EG(argument_stack)->top += extra;
|
||||
/* store old top on the stack */
|
||||
*EG(argument_stack)->top = (void*)old_top;
|
||||
EG(argument_stack)->top += ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*);
|
||||
}
|
||||
} else {
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED((int)size);
|
||||
}
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(used_stack);
|
||||
call = (zend_execute_data*)EG(argument_stack)->top;
|
||||
EG(argument_stack)->top += used_stack;
|
||||
call->func = func;
|
||||
call->num_args = 0;
|
||||
call->flags = flags;
|
||||
call->called_scope = called_scope;
|
||||
call->object = object;
|
||||
call->prev_nested_call = prev;
|
||||
return call;
|
||||
ret = (void*)EG(argument_stack)->top;
|
||||
EG(argument_stack)->top += size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
|
||||
static zend_always_inline void** zend_vm_stack_frame_base(zend_execute_data *ex)
|
||||
{
|
||||
uint32_t first_extra_arg = call->func->op_array.num_args - ((call->func->common.fn_flags & ZEND_ACC_VARIADIC) != 0);
|
||||
|
||||
if (UNEXPECTED(call->num_args > first_extra_arg)) {
|
||||
zval *end = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
||||
zval *p = end + (call->num_args - first_extra_arg);
|
||||
do {
|
||||
p--;
|
||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
} while (p != end);
|
||||
}
|
||||
return (void**)((char*)ex->call_slots +
|
||||
ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * ex->op_array->nested_calls);
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call TSRMLS_DC)
|
||||
static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
|
||||
{
|
||||
uint32_t num_args = call->num_args;
|
||||
|
||||
if (num_args > 0) {
|
||||
zval *end = ZEND_CALL_ARG(call, 1);
|
||||
zval *p = end + num_args;
|
||||
|
||||
do {
|
||||
p--;
|
||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
} while (p != end);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free_call_frame(zend_execute_data *call TSRMLS_DC)
|
||||
{
|
||||
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (zval*)call)) {
|
||||
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
|
||||
zend_vm_stack p = EG(argument_stack);
|
||||
|
||||
EG(argument_stack) = p->prev;
|
||||
efree(p);
|
||||
} else {
|
||||
EG(argument_stack)->top = (zval*)call;
|
||||
EG(argument_stack)->top = (void**)ptr;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
|
||||
{
|
||||
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
|
||||
zend_vm_stack p = EG(argument_stack);
|
||||
|
||||
EG(argument_stack) = p->prev;
|
||||
efree(p);
|
||||
} else {
|
||||
/* the following comparison must be optimized out at compile time */
|
||||
if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
|
||||
ptr = (void*)(((char*)ptr) - ZEND_MM_ALIGNED_SIZE(sizeof(void*)));
|
||||
EG(argument_stack)->top = *(void***)ptr;
|
||||
} else {
|
||||
EG(argument_stack)->top = (void**)ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC)
|
||||
{
|
||||
void **p = EG(argument_stack)->top - 1;
|
||||
void **end = p - (int)(zend_uintptr_t)*p;
|
||||
|
||||
while (p != end) {
|
||||
zval *q = (zval *) *(--p);
|
||||
*p = NULL;
|
||||
i_zval_ptr_dtor(q ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
}
|
||||
if (nested) {
|
||||
EG(argument_stack)->top = p;
|
||||
} else {
|
||||
zend_vm_stack_free_int(p TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data *ex)
|
||||
{
|
||||
if (ex) {
|
||||
void **p = ex->function_state.arguments;
|
||||
return (int)(zend_uintptr_t) *p;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline zval** zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
|
||||
{
|
||||
void **p = ex->function_state.arguments;
|
||||
int arg_count = (int)(zend_uintptr_t) *p;
|
||||
|
||||
if (UNEXPECTED(requested_arg > arg_count)) {
|
||||
return NULL;
|
||||
}
|
||||
return (zval**)p - arg_count + requested_arg - 1;
|
||||
}
|
||||
|
||||
static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
|
||||
{
|
||||
return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data);
|
||||
}
|
||||
|
||||
static zend_always_inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
|
||||
{
|
||||
return zend_vm_stack_get_arg_ex(EG(current_execute_data)->prev_execute_data, requested_arg);
|
||||
}
|
||||
|
||||
void execute_new_code(TSRMLS_D);
|
||||
|
||||
|
||||
@@ -279,28 +355,26 @@ ZEND_API const char *zend_get_executed_filename(TSRMLS_D);
|
||||
ZEND_API uint zend_get_executed_lineno(TSRMLS_D);
|
||||
ZEND_API zend_bool zend_is_executing(TSRMLS_D);
|
||||
|
||||
ZEND_API void zend_set_timeout(zend_long seconds, int reset_signals);
|
||||
ZEND_API void zend_set_timeout(long seconds, int reset_signals);
|
||||
ZEND_API void zend_unset_timeout(TSRMLS_D);
|
||||
ZEND_API void zend_timeout(int dummy);
|
||||
ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
|
||||
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim TSRMLS_DC);
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC);
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
void zend_init_timeout_thread(void);
|
||||
void zend_shutdown_timeout_thread(void);
|
||||
#define WM_REGISTER_ZEND_TIMEOUT (WM_USER+1)
|
||||
#define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
|
||||
#endif
|
||||
#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
|
||||
#define zendi_zval_dtor(p) zval_dtor(&(p))
|
||||
|
||||
#define active_opline (*EG(opline_ptr))
|
||||
|
||||
/* The following tries to resolve the classname of a zval of type object.
|
||||
* Since it is slow it should be only used in error messages.
|
||||
*/
|
||||
#define Z_OBJ_CLASS_NAME_P(obj) (((obj) && (obj)->handlers->get_class_entry != NULL && (obj)->handlers->get_class_entry) ? (obj)->handlers->get_class_entry(obj TSRMLS_CC)->name->val : "")
|
||||
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "")
|
||||
|
||||
ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var);
|
||||
ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var);
|
||||
|
||||
#define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
|
||||
#define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
|
||||
@@ -315,47 +389,33 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode);
|
||||
|
||||
/* former zend_execute_locks.h */
|
||||
typedef struct _zend_free_op {
|
||||
zval *var;
|
||||
zval* var;
|
||||
/* int is_var; */
|
||||
} zend_free_op;
|
||||
|
||||
ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
|
||||
ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
|
||||
|
||||
ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
|
||||
|
||||
void zend_clean_and_cache_symbol_table(zend_array *symbol_table TSRMLS_DC);
|
||||
void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC);
|
||||
void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC);
|
||||
|
||||
#define CACHED_PTR(num) \
|
||||
EX(run_time_cache)[(num)]
|
||||
EG(active_op_array)->run_time_cache[(num)]
|
||||
|
||||
#define CACHE_PTR(num, ptr) do { \
|
||||
EX(run_time_cache)[(num)] = (ptr); \
|
||||
EG(active_op_array)->run_time_cache[(num)] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_POLYMORPHIC_PTR(num, ce) \
|
||||
((EX(run_time_cache)[(num)] == (ce)) ? \
|
||||
EX(run_time_cache)[(num) + 1] : \
|
||||
((EG(active_op_array)->run_time_cache[(num)] == (ce)) ? \
|
||||
EG(active_op_array)->run_time_cache[(num) + 1] : \
|
||||
NULL)
|
||||
|
||||
#define CACHE_POLYMORPHIC_PTR(num, ce, ptr) do { \
|
||||
EX(run_time_cache)[(num)] = (ce); \
|
||||
EX(run_time_cache)[(num) + 1] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_PTR_EX(slot) \
|
||||
(slot)[0]
|
||||
|
||||
#define CACHE_PTR_EX(slot, ptr) do { \
|
||||
(slot)[0] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_POLYMORPHIC_PTR_EX(slot, ce) \
|
||||
(((slot)[0] == (ce)) ? (slot)[1] : NULL)
|
||||
|
||||
#define CACHE_POLYMORPHIC_PTR_EX(slot, ce, ptr) do { \
|
||||
(slot)[0] = (ce); \
|
||||
(slot)[1] = (ptr); \
|
||||
EG(active_op_array)->run_time_cache[(num)] = (ce); \
|
||||
EG(active_op_array)->run_time_cache[(num) + 1] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
+579
-724
File diff suppressed because it is too large.
Load diff
@@ -24,7 +24,7 @@
|
||||
ZEND_API zend_llist zend_extensions;
|
||||
static int last_resource_number;
|
||||
|
||||
int zend_load_extension(const char *path TSRMLS_DC)
|
||||
int zend_load_extension(const char *path)
|
||||
{
|
||||
#if ZEND_EXTENSIONS_SUPPORT
|
||||
DL_HANDLE handle;
|
||||
@@ -107,7 +107,7 @@ int zend_load_extension(const char *path TSRMLS_DC)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return zend_register_extension(new_extension, handle TSRMLS_CC);
|
||||
return zend_register_extension(new_extension, handle);
|
||||
#else
|
||||
fprintf(stderr, "Extensions are not supported on this platform.\n");
|
||||
/* See http://support.microsoft.com/kb/190351 */
|
||||
@@ -119,7 +119,7 @@ int zend_load_extension(const char *path TSRMLS_DC)
|
||||
}
|
||||
|
||||
|
||||
int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle TSRMLS_DC)
|
||||
int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
|
||||
{
|
||||
#if ZEND_EXTENSIONS_SUPPORT
|
||||
zend_extension extension;
|
||||
@@ -127,7 +127,7 @@ int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle TSRM
|
||||
extension = *new_extension;
|
||||
extension.handle = handle;
|
||||
|
||||
zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension TSRMLS_CC);
|
||||
zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
|
||||
|
||||
zend_llist_add_element(&zend_extensions, &extension);
|
||||
|
||||
@@ -208,8 +208,10 @@ static void zend_extension_message_dispatcher(const zend_extension *extension, i
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_extension_dispatch_message(int message, void *arg TSRMLS_DC)
|
||||
ZEND_API void zend_extension_dispatch_message(int message, void *arg)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher TSRMLS_CC, 2, message, arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/* The first number is the engine version and the rest is the date.
|
||||
* This way engine 2/3 API no. is always greater than engine 1 API no..
|
||||
*/
|
||||
#define ZEND_EXTENSION_API_NO 220140815
|
||||
#define ZEND_EXTENSION_API_NO 220131226
|
||||
|
||||
typedef struct _zend_extension_version_info {
|
||||
int zend_extension_api_no;
|
||||
@@ -94,7 +94,7 @@ struct _zend_extension {
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_get_resource_handle(zend_extension *extension);
|
||||
ZEND_API void zend_extension_dispatch_message(int message, void *arg TSRMLS_DC);
|
||||
ZEND_API void zend_extension_dispatch_message(int message, void *arg);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_EXTMSG_NEW_EXTENSION 1
|
||||
@@ -111,14 +111,14 @@ END_EXTERN_C()
|
||||
ZEND_API extern zend_llist zend_extensions;
|
||||
|
||||
void zend_extension_dtor(zend_extension *extension);
|
||||
void zend_append_version_info(const zend_extension *extension);
|
||||
ZEND_API void zend_append_version_info(const zend_extension *extension);
|
||||
int zend_startup_extensions_mechanism(void);
|
||||
int zend_startup_extensions(void);
|
||||
void zend_shutdown_extensions(TSRMLS_D);
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_load_extension(const char *path TSRMLS_DC);
|
||||
ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle TSRMLS_DC);
|
||||
ZEND_API int zend_load_extension(const char *path);
|
||||
ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle);
|
||||
ZEND_API zend_extension *zend_get_extension(const char *extension_name);
|
||||
END_EXTERN_C()
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef ZEND_FLOAT_H
|
||||
#define ZEND_FLOAT_H
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
/*
|
||||
Define functions for FP initialization and de-initialization.
|
||||
*/
|
||||
@@ -28,6 +30,8 @@ extern ZEND_API void zend_init_fpu(TSRMLS_D);
|
||||
extern ZEND_API void zend_shutdown_fpu(TSRMLS_D);
|
||||
extern ZEND_API void zend_ensure_fpu_mode(TSRMLS_D);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
/* Copy of the contents of xpfpa.h (which is under public domain)
|
||||
See http://wiki.php.net/rfc/rounding for details.
|
||||
|
||||
|
||||
+555
-525
File diff suppressed because it is too large.
Load diff
+131
-42
@@ -40,46 +40,62 @@
|
||||
# define GC_BENCH_PEAK(peak, counter)
|
||||
#endif
|
||||
|
||||
#define GC_COLOR 0xc000
|
||||
#define GC_COLOR 0x03
|
||||
|
||||
#define GC_BLACK 0x0000
|
||||
#define GC_WHITE 0x8000
|
||||
#define GC_GREY 0x4000
|
||||
#define GC_PURPLE 0xc000
|
||||
#define GC_BLACK 0x00
|
||||
#define GC_WHITE 0x01
|
||||
#define GC_GREY 0x02
|
||||
#define GC_PURPLE 0x03
|
||||
|
||||
#define GC_ADDRESS(v) \
|
||||
((v) & ~GC_COLOR)
|
||||
((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))
|
||||
#define GC_SET_ADDRESS(v, a) \
|
||||
do {(v) = ((v) & GC_COLOR) | (a);} while (0)
|
||||
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a))))
|
||||
#define GC_GET_COLOR(v) \
|
||||
(((zend_uintptr_t)(v)) & GC_COLOR)
|
||||
#define GC_SET_COLOR(v, c) \
|
||||
do {(v) = ((v) & ~GC_COLOR) | (c);} while (0)
|
||||
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c)))
|
||||
#define GC_SET_BLACK(v) \
|
||||
do {(v) = (v) & ~GC_COLOR;} while (0)
|
||||
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))
|
||||
#define GC_SET_PURPLE(v) \
|
||||
do {(v) = (v) | GC_COLOR;} while (0)
|
||||
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE))
|
||||
|
||||
#define GC_ZVAL_INIT(z) \
|
||||
((zval_gc_info*)(z))->u.buffered = NULL
|
||||
#define GC_ZVAL_ADDRESS(v) \
|
||||
GC_ADDRESS(Z_GC_INFO_P(v))
|
||||
GC_ADDRESS(((zval_gc_info*)(v))->u.buffered)
|
||||
#define GC_ZVAL_SET_ADDRESS(v, a) \
|
||||
GC_SET_ADDRESS(Z_GC_INFO_P(v), (a))
|
||||
GC_SET_ADDRESS(((zval_gc_info*)(v))->u.buffered, (a))
|
||||
#define GC_ZVAL_GET_COLOR(v) \
|
||||
GC_GET_COLOR(Z_GC_INFO_P(v))
|
||||
GC_GET_COLOR(((zval_gc_info*)(v))->u.buffered)
|
||||
#define GC_ZVAL_SET_COLOR(v, c) \
|
||||
GC_SET_COLOR(Z_GC_INFO_P(v), (c))
|
||||
GC_SET_COLOR(((zval_gc_info*)(v))->u.buffered, (c))
|
||||
#define GC_ZVAL_SET_BLACK(v) \
|
||||
GC_SET_BLACK(Z_GC_INFO_P(v))
|
||||
GC_SET_BLACK(((zval_gc_info*)(v))->u.buffered)
|
||||
#define GC_ZVAL_SET_PURPLE(v) \
|
||||
GC_SET_PURPLE(Z_GC_INFO_P(v))
|
||||
GC_SET_PURPLE(((zval_gc_info*)(v))->u.buffered)
|
||||
|
||||
#define GC_OBJ_INIT(z) \
|
||||
(z)->buffered = NULL
|
||||
|
||||
typedef struct _gc_root_buffer {
|
||||
zend_refcounted *ref;
|
||||
struct _gc_root_buffer *next; /* double-linked list */
|
||||
struct _gc_root_buffer *prev;
|
||||
uint32_t refcount;
|
||||
struct _gc_root_buffer *prev; /* double-linked list */
|
||||
struct _gc_root_buffer *next;
|
||||
zend_object_handle handle; /* must be 0 for zval */
|
||||
union {
|
||||
zval *pz;
|
||||
const zend_object_handlers *handlers;
|
||||
} u;
|
||||
} gc_root_buffer;
|
||||
|
||||
typedef struct _zval_gc_info {
|
||||
zval z;
|
||||
union {
|
||||
gc_root_buffer *buffered;
|
||||
struct _zval_gc_info *next;
|
||||
} u;
|
||||
} zval_gc_info;
|
||||
|
||||
typedef struct _zend_gc_globals {
|
||||
zend_bool gc_enabled;
|
||||
zend_bool gc_active;
|
||||
@@ -90,19 +106,24 @@ typedef struct _zend_gc_globals {
|
||||
gc_root_buffer *first_unused; /* pointer to first unused buffer */
|
||||
gc_root_buffer *last_unused; /* pointer to last unused buffer */
|
||||
|
||||
gc_root_buffer to_free; /* list to free */
|
||||
gc_root_buffer *next_to_free;
|
||||
zval_gc_info *zval_to_free; /* temporary list of zvals to free */
|
||||
zval_gc_info *free_list;
|
||||
zval_gc_info *next_to_free;
|
||||
|
||||
uint32_t gc_runs;
|
||||
uint32_t collected;
|
||||
zend_uint gc_runs;
|
||||
zend_uint collected;
|
||||
|
||||
#if GC_BENCH
|
||||
uint32_t root_buf_length;
|
||||
uint32_t root_buf_peak;
|
||||
uint32_t zval_possible_root;
|
||||
uint32_t zval_buffered;
|
||||
uint32_t zval_remove_from_buffer;
|
||||
uint32_t zval_marked_grey;
|
||||
zend_uint root_buf_length;
|
||||
zend_uint root_buf_peak;
|
||||
zend_uint zval_possible_root;
|
||||
zend_uint zobj_possible_root;
|
||||
zend_uint zval_buffered;
|
||||
zend_uint zobj_buffered;
|
||||
zend_uint zval_remove_from_buffer;
|
||||
zend_uint zobj_remove_from_buffer;
|
||||
zend_uint zval_marked_grey;
|
||||
zend_uint zobj_marked_grey;
|
||||
#endif
|
||||
|
||||
} zend_gc_globals;
|
||||
@@ -119,8 +140,9 @@ extern ZEND_API zend_gc_globals gc_globals;
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int gc_collect_cycles(TSRMLS_D);
|
||||
ZEND_API void gc_possible_root(zend_refcounted *ref TSRMLS_DC);
|
||||
ZEND_API void gc_remove_from_buffer(zend_refcounted *ref TSRMLS_DC);
|
||||
ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC);
|
||||
ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC);
|
||||
ZEND_API void gc_remove_zval_from_buffer(zval *zv TSRMLS_DC);
|
||||
ZEND_API void gc_globals_ctor(TSRMLS_D);
|
||||
ZEND_API void gc_globals_dtor(TSRMLS_D);
|
||||
ZEND_API void gc_init(TSRMLS_D);
|
||||
@@ -128,23 +150,90 @@ ZEND_API void gc_reset(TSRMLS_D);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define GC_ZVAL_CHECK_POSSIBLE_ROOT(z) \
|
||||
gc_check_possible_root((z) TSRMLS_CC)
|
||||
gc_zval_check_possible_root((z) TSRMLS_CC)
|
||||
|
||||
#define GC_REMOVE_FROM_BUFFER(p) do { \
|
||||
zend_refcounted *_p = (zend_refcounted*)(p); \
|
||||
if (GC_ADDRESS(GC_INFO(_p))) { \
|
||||
gc_remove_from_buffer(_p TSRMLS_CC); \
|
||||
} \
|
||||
#define GC_REMOVE_FROM_BUFFER(current) \
|
||||
gc_remove_from_buffer((current) TSRMLS_CC)
|
||||
|
||||
#define GC_REMOVE_ZVAL_FROM_BUFFER(z) \
|
||||
if (GC_ADDRESS(((zval_gc_info*)z)->u.buffered)) { \
|
||||
gc_remove_zval_from_buffer(z TSRMLS_CC); \
|
||||
}
|
||||
|
||||
#define GC_ZOBJ_CHECK_POSSIBLE_ROOT(zobject) \
|
||||
do { \
|
||||
if (EXPECTED(EG(objects_store).object_buckets != NULL) && \
|
||||
EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)].valid) { \
|
||||
gc_zobj_possible_root(zobject TSRMLS_CC); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static zend_always_inline void gc_check_possible_root(zval *z TSRMLS_DC)
|
||||
#define GC_REMOVE_ZOBJ_FROM_BUFFER(obj) \
|
||||
do { \
|
||||
if (GC_ADDRESS((obj)->buffered) && !GC_G(gc_active)) { \
|
||||
GC_BENCH_INC(zobj_remove_from_buffer); \
|
||||
GC_REMOVE_FROM_BUFFER(GC_ADDRESS((obj)->buffered)); \
|
||||
(obj)->buffered = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static zend_always_inline void gc_zval_check_possible_root(zval *z TSRMLS_DC)
|
||||
{
|
||||
ZVAL_DEREF(z);
|
||||
if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
|
||||
gc_possible_root(Z_COUNTED_P(z) TSRMLS_CC);
|
||||
if (z->type == IS_ARRAY || z->type == IS_OBJECT) {
|
||||
gc_zval_possible_root(z TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void gc_remove_from_buffer(gc_root_buffer *root TSRMLS_DC)
|
||||
{
|
||||
root->next->prev = root->prev;
|
||||
root->prev->next = root->next;
|
||||
root->prev = GC_G(unused);
|
||||
GC_G(unused) = root;
|
||||
GC_BENCH_DEC(root_buf_length);
|
||||
}
|
||||
|
||||
#define ALLOC_PERMANENT_ZVAL(z) \
|
||||
do { \
|
||||
(z) = (zval*)malloc(sizeof(zval_gc_info)); \
|
||||
GC_ZVAL_INIT(z); \
|
||||
} while (0)
|
||||
|
||||
/* The following macros override macros from zend_alloc.h */
|
||||
#undef ALLOC_ZVAL
|
||||
#define ALLOC_ZVAL(z) \
|
||||
do { \
|
||||
(z) = (zval*)emalloc(sizeof(zval_gc_info)); \
|
||||
GC_ZVAL_INIT(z); \
|
||||
} while (0)
|
||||
|
||||
#undef FREE_ZVAL
|
||||
#define FREE_ZVAL(z) \
|
||||
do { \
|
||||
GC_REMOVE_ZVAL_FROM_BUFFER(z); \
|
||||
efree(z); \
|
||||
} while (0)
|
||||
|
||||
#undef ALLOC_ZVAL_REL
|
||||
#define ALLOC_ZVAL_REL(z) \
|
||||
do { \
|
||||
(z) = (zval*)emalloc_rel(sizeof(zval_gc_info)); \
|
||||
GC_ZVAL_INIT(z); \
|
||||
} while (0)
|
||||
|
||||
#undef FREE_ZVAL_REL
|
||||
#define FREE_ZVAL_REL(z) \
|
||||
do { \
|
||||
GC_REMOVE_ZVAL_FROM_BUFFER(z); \
|
||||
efree_rel(z); \
|
||||
} while (0)
|
||||
|
||||
#define FREE_ZVAL_EX(z) \
|
||||
efree(z)
|
||||
|
||||
#define FREE_ZVAL_REL_EX(z) \
|
||||
efree_rel(z)
|
||||
|
||||
#endif /* ZEND_GC_H */
|
||||
|
||||
/*
|
||||
|
||||
+178
-117
@@ -27,15 +27,15 @@
|
||||
ZEND_API zend_class_entry *zend_ce_generator;
|
||||
static zend_object_handlers zend_generator_handlers;
|
||||
|
||||
static zend_object *zend_generator_create(zend_class_entry *class_type TSRMLS_DC);
|
||||
static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC);
|
||||
|
||||
static void zend_generator_cleanup_unfinished_execution(zend_generator *generator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_execute_data *execute_data = generator->execute_data;
|
||||
zend_op_array *op_array = &execute_data->func->op_array;
|
||||
zend_op_array *op_array = execute_data->op_array;
|
||||
|
||||
if (generator->send_target) {
|
||||
if (Z_REFCOUNTED_P(generator->send_target)) Z_DELREF_P(generator->send_target);
|
||||
Z_DELREF_PP(generator->send_target);
|
||||
generator->send_target = NULL;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
||||
{
|
||||
/* -1 required because we want the last run opcode, not the
|
||||
* next to-be-run one. */
|
||||
uint32_t op_num = execute_data->opline - op_array->opcodes - 1;
|
||||
zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < op_array->last_brk_cont; ++i) {
|
||||
@@ -60,14 +60,14 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
||||
switch (brk_opline->opcode) {
|
||||
case ZEND_SWITCH_FREE:
|
||||
{
|
||||
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
|
||||
zval_ptr_dtor(var);
|
||||
temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
|
||||
zval_ptr_dtor(&var->var.ptr);
|
||||
}
|
||||
break;
|
||||
case ZEND_FREE:
|
||||
{
|
||||
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
|
||||
zval_dtor(var);
|
||||
temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
|
||||
zval_dtor(&var->tmp_var);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -75,32 +75,42 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear any backed up stack arguments */
|
||||
{
|
||||
void **ptr = generator->stack->top - 1;
|
||||
void **end = zend_vm_stack_frame_base(execute_data);
|
||||
|
||||
for (; ptr >= end; --ptr) {
|
||||
zval_ptr_dtor((zval **) ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* If yield was used as a function argument there may be active
|
||||
* method calls those objects need to be freed */
|
||||
while (execute_data->call) {
|
||||
while (execute_data->call >= execute_data->call_slots) {
|
||||
if (execute_data->call->object) {
|
||||
OBJ_RELEASE(execute_data->call->object);
|
||||
zval_ptr_dtor(&execute_data->call->object);
|
||||
}
|
||||
execute_data->call = execute_data->call->prev_nested_call;
|
||||
execute_data->call--;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (Z_TYPE(generator->value) != IS_UNDEF) {
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
ZVAL_UNDEF(&generator->value);
|
||||
generator->value = NULL;
|
||||
}
|
||||
|
||||
if (Z_TYPE(generator->key) != IS_UNDEF) {
|
||||
if (generator->key) {
|
||||
zval_ptr_dtor(&generator->key);
|
||||
ZVAL_UNDEF(&generator->key);
|
||||
generator->key = NULL;
|
||||
}
|
||||
|
||||
if (generator->execute_data) {
|
||||
zend_execute_data *execute_data = generator->execute_data;
|
||||
zend_op_array *op_array = &execute_data->func->op_array;
|
||||
zend_op_array *op_array = execute_data->op_array;
|
||||
|
||||
if (!execute_data->symbol_table) {
|
||||
zend_free_compiled_variables(execute_data TSRMLS_CC);
|
||||
@@ -108,8 +118,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (execute_data->object) {
|
||||
OBJ_RELEASE(execute_data->object);
|
||||
if (execute_data->current_this) {
|
||||
zval_ptr_dtor(&execute_data->current_this);
|
||||
}
|
||||
|
||||
/* A fatal error / die occurred during the generator execution. Trying to clean
|
||||
@@ -119,7 +129,23 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
return;
|
||||
}
|
||||
|
||||
zend_vm_stack_free_extra_args(generator->execute_data TSRMLS_CC);
|
||||
/* We have added an additional stack frame in prev_execute_data, so we
|
||||
* have to free it. It also contains the arguments passed to the
|
||||
* generator (for func_get_args) so those have to be freed too. */
|
||||
{
|
||||
zend_execute_data *prev_execute_data = execute_data->prev_execute_data;
|
||||
void **arguments = prev_execute_data->function_state.arguments;
|
||||
|
||||
if (arguments) {
|
||||
int arguments_count = (int) (zend_uintptr_t) *arguments;
|
||||
zval **arguments_start = (zval **) (arguments - arguments_count);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < arguments_count; ++i) {
|
||||
zval_ptr_dtor(arguments_start + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Some cleanups are only necessary if the generator was closued
|
||||
* before it could finish execution (reach a return statement). */
|
||||
@@ -139,25 +165,24 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
static void zend_generator_dtor_storage(zend_generator *generator, zend_object_handle handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*) object;
|
||||
zend_execute_data *ex = generator->execute_data;
|
||||
uint32_t op_num, finally_op_num;
|
||||
zend_uint op_num, finally_op_num;
|
||||
int i;
|
||||
|
||||
if (!ex || !ex->func->op_array.has_finally_block) {
|
||||
if (!ex || !ex->op_array->has_finally_block) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* -1 required because we want the last run opcode, not the
|
||||
* next to-be-run one. */
|
||||
op_num = ex->opline - ex->func->op_array.opcodes - 1;
|
||||
op_num = ex->opline - ex->op_array->opcodes - 1;
|
||||
|
||||
/* Find next finally block */
|
||||
finally_op_num = 0;
|
||||
for (i = 0; i < ex->func->op_array.last_try_catch; i++) {
|
||||
zend_try_catch_element *try_catch = &ex->func->op_array.try_catch_array[i];
|
||||
for (i = 0; i < ex->op_array->last_try_catch; i++) {
|
||||
zend_try_catch_element *try_catch = &ex->op_array->try_catch_array[i];
|
||||
|
||||
if (op_num < try_catch->try_op) {
|
||||
break;
|
||||
@@ -171,7 +196,7 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
/* If a finally block was found we jump directly to it and
|
||||
* resume the generator. */
|
||||
if (finally_op_num) {
|
||||
ex->opline = &ex->func->op_array.opcodes[finally_op_num];
|
||||
ex->opline = &ex->op_array->opcodes[finally_op_num];
|
||||
ex->fast_ret = NULL;
|
||||
generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
@@ -179,23 +204,19 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_generator_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*) object;
|
||||
|
||||
zend_generator_close(generator, 0 TSRMLS_CC);
|
||||
|
||||
zend_object_std_dtor(&generator->std TSRMLS_CC);
|
||||
|
||||
if (generator->iterator) {
|
||||
zend_iterator_dtor(generator->iterator TSRMLS_CC);
|
||||
}
|
||||
efree(generator);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object *zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator;
|
||||
zend_object_value object;
|
||||
|
||||
generator = emalloc(sizeof(zend_generator));
|
||||
memset(generator, 0, sizeof(zend_generator));
|
||||
@@ -204,28 +225,37 @@ static zend_object *zend_generator_create(zend_class_entry *class_type TSRMLS_DC
|
||||
generator->largest_used_integer_key = -1;
|
||||
|
||||
zend_object_std_init(&generator->std, class_type TSRMLS_CC);
|
||||
generator->std.handlers = &zend_generator_handlers;
|
||||
|
||||
return (zend_object*)generator;
|
||||
object.handle = zend_objects_store_put(generator,
|
||||
(zend_objects_store_dtor_t) zend_generator_dtor_storage,
|
||||
(zend_objects_free_object_storage_t) zend_generator_free_storage,
|
||||
NULL TSRMLS_CC
|
||||
);
|
||||
object.handlers = &zend_generator_handlers;
|
||||
|
||||
return object;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int copy_closure_static_var(zval *var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
|
||||
static void copy_closure_static_var(zval **var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
|
||||
{
|
||||
HashTable *target = va_arg(args, HashTable *);
|
||||
|
||||
ZVAL_MAKE_REF(var);
|
||||
Z_ADDREF_P(var);
|
||||
zend_hash_update(target, key->key, var);
|
||||
return 0;
|
||||
SEPARATE_ZVAL_TO_MAKE_IS_REF(var);
|
||||
Z_ADDREF_PP(var);
|
||||
zend_hash_quick_update(target, key->arKey, key->nKeyLength, key->h, var, sizeof(zval *), NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Requires globals EG(scope), EG(This) and EG(current_execute_data). */
|
||||
ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
|
||||
/* Requires globals EG(scope), EG(current_scope), EG(This),
|
||||
* EG(active_symbol_table) and EG(current_execute_data). */
|
||||
ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *return_value;
|
||||
zend_generator *generator;
|
||||
zend_execute_data *current_execute_data;
|
||||
zend_op **opline_ptr;
|
||||
HashTable *current_symbol_table;
|
||||
zend_execute_data *execute_data;
|
||||
zend_vm_stack current_stack = EG(argument_stack);
|
||||
|
||||
@@ -245,8 +275,8 @@ ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array
|
||||
);
|
||||
zend_hash_apply_with_arguments(
|
||||
op_array->static_variables TSRMLS_CC,
|
||||
copy_closure_static_var, 1,
|
||||
op_array_copy->static_variables
|
||||
(apply_func_args_t) copy_closure_static_var,
|
||||
1, op_array_copy->static_variables
|
||||
);
|
||||
}
|
||||
|
||||
@@ -254,30 +284,41 @@ ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array
|
||||
}
|
||||
|
||||
/* Create new execution context. We have to back up and restore
|
||||
* EG(current_execute_data) here. */
|
||||
* EG(current_execute_data), EG(opline_ptr) and EG(active_symbol_table)
|
||||
* here because the function modifies or uses them */
|
||||
current_execute_data = EG(current_execute_data);
|
||||
execute_data = zend_create_generator_execute_data(call, op_array, return_value TSRMLS_CC);
|
||||
opline_ptr = EG(opline_ptr);
|
||||
current_symbol_table = EG(active_symbol_table);
|
||||
EG(active_symbol_table) = NULL;
|
||||
execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
|
||||
EG(active_symbol_table) = current_symbol_table;
|
||||
EG(current_execute_data) = current_execute_data;
|
||||
EG(opline_ptr) = opline_ptr;
|
||||
|
||||
ALLOC_INIT_ZVAL(return_value);
|
||||
object_init_ex(return_value, zend_ce_generator);
|
||||
|
||||
if (Z_OBJ(EG(This))) {
|
||||
Z_ADDREF(EG(This));
|
||||
if (EG(This)) {
|
||||
Z_ADDREF_P(EG(This));
|
||||
}
|
||||
|
||||
/* Back up executor globals. */
|
||||
execute_data->current_scope = EG(scope);
|
||||
execute_data->current_called_scope = EG(called_scope);
|
||||
execute_data->symbol_table = EG(active_symbol_table);
|
||||
execute_data->current_this = EG(This);
|
||||
|
||||
/* Save execution context in generator object. */
|
||||
generator = (zend_generator *) Z_OBJ_P(return_value);
|
||||
execute_data->prev_execute_data = NULL;
|
||||
generator = (zend_generator *) zend_object_store_get_object(return_value TSRMLS_CC);
|
||||
generator->execute_data = execute_data;
|
||||
generator->stack = EG(argument_stack);
|
||||
EG(argument_stack) = current_stack;
|
||||
|
||||
/* EX(return_value) keeps pointer to zend_object (not a real zval) */
|
||||
execute_data->return_value = (zval*)generator;
|
||||
return return_value;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_function *zend_generator_get_constructor(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
static zend_function *zend_generator_get_constructor(zval *object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_error(E_RECOVERABLE_ERROR, "The \"Generator\" class is reserved for internal use and cannot be manually instantiated");
|
||||
|
||||
@@ -301,39 +342,52 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
|
||||
|
||||
{
|
||||
/* Backup executor globals */
|
||||
zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
|
||||
zend_execute_data *original_execute_data = EG(current_execute_data);
|
||||
zend_object *original_This;
|
||||
zend_op **original_opline_ptr = EG(opline_ptr);
|
||||
zend_op_array *original_active_op_array = EG(active_op_array);
|
||||
HashTable *original_active_symbol_table = EG(active_symbol_table);
|
||||
zval *original_This = EG(This);
|
||||
zend_class_entry *original_scope = EG(scope);
|
||||
zend_class_entry *original_called_scope = EG(called_scope);
|
||||
zend_vm_stack original_stack = EG(argument_stack);
|
||||
|
||||
original_This = Z_OBJ(EG(This));
|
||||
/* We (mis)use the return_value_ptr_ptr to provide the generator object
|
||||
* to the executor, so YIELD will be able to set the yielded value */
|
||||
EG(return_value_ptr_ptr) = (zval **) generator;
|
||||
|
||||
/* Set executor globals */
|
||||
EG(current_execute_data) = generator->execute_data;
|
||||
Z_OBJ(EG(This)) = generator->execute_data->object;
|
||||
EG(scope) = generator->execute_data->scope;
|
||||
EG(opline_ptr) = &generator->execute_data->opline;
|
||||
EG(active_op_array) = generator->execute_data->op_array;
|
||||
EG(active_symbol_table) = generator->execute_data->symbol_table;
|
||||
EG(This) = generator->execute_data->current_this;
|
||||
EG(scope) = generator->execute_data->current_scope;
|
||||
EG(called_scope) = generator->execute_data->current_called_scope;
|
||||
EG(argument_stack) = generator->stack;
|
||||
|
||||
/* We want the backtrace to look as if the generator function was
|
||||
* called from whatever method we are current running (e.g. next()).
|
||||
* So we have to link generator call frame with caller call frames */
|
||||
|
||||
generator->execute_data->prev_execute_data = original_execute_data;
|
||||
* The first prev_execute_data contains an additional stack frame,
|
||||
* which makes the generator function show up in the backtrace and
|
||||
* makes the arguments available to func_get_args(). So we have to
|
||||
* set the prev_execute_data of that prev_execute_data :) */
|
||||
generator->execute_data->prev_execute_data->prev_execute_data = original_execute_data;
|
||||
|
||||
/* Resume execution */
|
||||
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
|
||||
zend_execute_ex(generator->execute_data TSRMLS_CC);
|
||||
generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
|
||||
|
||||
/* Unlink generator call_frame from the caller */
|
||||
if (generator->execute_data) {
|
||||
generator->execute_data->prev_execute_data = NULL;
|
||||
}
|
||||
|
||||
/* Restore executor globals */
|
||||
EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
|
||||
EG(current_execute_data) = original_execute_data;
|
||||
Z_OBJ(EG(This)) = original_This;
|
||||
EG(opline_ptr) = original_opline_ptr;
|
||||
EG(active_op_array) = original_active_op_array;
|
||||
EG(active_symbol_table) = original_active_symbol_table;
|
||||
EG(This) = original_This;
|
||||
EG(scope) = original_scope;
|
||||
EG(called_scope) = original_called_scope;
|
||||
EG(argument_stack) = original_stack;
|
||||
|
||||
/* If an exception was thrown in the generator we have to internally
|
||||
@@ -347,7 +401,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
|
||||
|
||||
static void zend_generator_ensure_initialized(zend_generator *generator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (generator->execute_data && Z_TYPE(generator->value) == IS_UNDEF) {
|
||||
if (generator->execute_data && !generator->value) {
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
|
||||
}
|
||||
@@ -374,7 +428,7 @@ ZEND_METHOD(Generator, rewind)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_rewind(generator TSRMLS_CC);
|
||||
}
|
||||
@@ -390,11 +444,11 @@ ZEND_METHOD(Generator, valid)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
RETURN_BOOL(Z_TYPE(generator->value) != IS_UNDEF);
|
||||
RETURN_BOOL(generator->value != NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -408,12 +462,12 @@ ZEND_METHOD(Generator, current)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(generator->value) != IS_UNDEF) {
|
||||
RETURN_ZVAL_FAST(&generator->value);
|
||||
if (generator->value) {
|
||||
RETURN_ZVAL_FAST(generator->value);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -428,12 +482,12 @@ ZEND_METHOD(Generator, key)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(generator->key) != IS_UNDEF) {
|
||||
RETURN_ZVAL_FAST(&generator->key);
|
||||
if (generator->key) {
|
||||
RETURN_ZVAL_FAST(generator->key);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -448,7 +502,7 @@ ZEND_METHOD(Generator, next)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
@@ -467,7 +521,7 @@ ZEND_METHOD(Generator, send)
|
||||
return;
|
||||
}
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
@@ -478,14 +532,15 @@ ZEND_METHOD(Generator, send)
|
||||
|
||||
/* Put sent value in the target VAR slot, if it is used */
|
||||
if (generator->send_target) {
|
||||
if (Z_REFCOUNTED_P(generator->send_target)) Z_DELREF_P(generator->send_target);
|
||||
ZVAL_COPY(generator->send_target, value);
|
||||
Z_DELREF_PP(generator->send_target);
|
||||
Z_ADDREF_P(value);
|
||||
*generator->send_target = value;
|
||||
}
|
||||
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(generator->value) != IS_UNDEF) {
|
||||
RETURN_ZVAL_FAST(&generator->value);
|
||||
if (generator->value) {
|
||||
RETURN_ZVAL_FAST(generator->value);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -494,16 +549,17 @@ ZEND_METHOD(Generator, send)
|
||||
* Throws an exception into the generator */
|
||||
ZEND_METHOD(Generator, throw)
|
||||
{
|
||||
zval *exception, exception_copy;
|
||||
zval *exception, *exception_copy;
|
||||
zend_generator *generator;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZVAL_DUP(&exception_copy, exception);
|
||||
ALLOC_ZVAL(exception_copy);
|
||||
MAKE_COPY_ZVAL(&exception, exception_copy);
|
||||
|
||||
generator = (zend_generator *) Z_OBJ_P(getThis());
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
@@ -512,19 +568,19 @@ ZEND_METHOD(Generator, throw)
|
||||
zend_execute_data *current_execute_data = EG(current_execute_data);
|
||||
EG(current_execute_data) = generator->execute_data;
|
||||
|
||||
zend_throw_exception_object(&exception_copy TSRMLS_CC);
|
||||
zend_throw_exception_object(exception_copy TSRMLS_CC);
|
||||
|
||||
EG(current_execute_data) = current_execute_data;
|
||||
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(generator->value) != IS_UNDEF) {
|
||||
RETURN_ZVAL_FAST(&generator->value);
|
||||
if (generator->value) {
|
||||
RETURN_ZVAL_FAST(generator->value);
|
||||
}
|
||||
} else {
|
||||
/* If the generator is already closed throw the exception in the
|
||||
* current context */
|
||||
zend_throw_exception_object(&exception_copy TSRMLS_CC);
|
||||
zend_throw_exception_object(exception_copy TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -549,41 +605,44 @@ ZEND_METHOD(Generator, __wakeup)
|
||||
|
||||
static void zend_generator_iterator_dtor(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
generator->iterator = NULL;
|
||||
zval_ptr_dtor(&iterator->data);
|
||||
zend_iterator_dtor(iterator TSRMLS_CC);
|
||||
zval *object = ((zend_generator_iterator *) iterator)->object;
|
||||
|
||||
zval_ptr_dtor(&object);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_generator_iterator_valid(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
return Z_TYPE(generator->value) != IS_UNDEF ? SUCCESS : FAILURE;
|
||||
return generator->value != NULL ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *zend_generator_iterator_get_data(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
static void zend_generator_iterator_get_data(zend_object_iterator *iterator, zval ***data TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
return &generator->value;
|
||||
if (generator->value) {
|
||||
*data = &generator->value;
|
||||
} else {
|
||||
*data = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval *key TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(generator->key) != IS_UNDEF) {
|
||||
ZVAL_ZVAL(key, &generator->key, 1, 0);
|
||||
if (generator->key) {
|
||||
ZVAL_ZVAL(key, generator->key, 1, 0);
|
||||
} else {
|
||||
ZVAL_NULL(key);
|
||||
}
|
||||
@@ -592,7 +651,7 @@ static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval
|
||||
|
||||
static void zend_generator_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
@@ -602,7 +661,7 @@ static void zend_generator_iterator_move_forward(zend_object_iterator *iterator
|
||||
|
||||
static void zend_generator_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data);
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_rewind(generator TSRMLS_CC);
|
||||
}
|
||||
@@ -619,27 +678,31 @@ static zend_object_iterator_funcs zend_generator_iterator_functions = {
|
||||
|
||||
zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object_iterator *iterator;
|
||||
zend_generator *generator = (zend_generator*)Z_OBJ_P(object);
|
||||
zend_generator_iterator *iterator;
|
||||
zend_generator *generator;
|
||||
|
||||
generator = (zend_generator *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
|
||||
if (!generator->execute_data) {
|
||||
zend_throw_exception(NULL, "Cannot traverse an already closed generator", 0 TSRMLS_CC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (by_ref && !(generator->execute_data->func->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
|
||||
if (by_ref && !(generator->execute_data->op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
|
||||
zend_throw_exception(NULL, "You can only iterate a generator by-reference if it declared that it yields by-reference", 0 TSRMLS_CC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iterator = generator->iterator = emalloc(sizeof(zend_object_iterator));
|
||||
|
||||
zend_iterator_init(iterator TSRMLS_CC);
|
||||
iterator = &generator->iterator;
|
||||
iterator->intern.funcs = &zend_generator_iterator_functions;
|
||||
iterator->intern.data = (void *) generator;
|
||||
|
||||
iterator->funcs = &zend_generator_iterator_functions;
|
||||
ZVAL_COPY(&iterator->data, object);
|
||||
/* We have to keep a reference to the generator object zval around,
|
||||
* otherwise the generator may be destroyed during iteration. */
|
||||
Z_ADDREF_P(object);
|
||||
iterator->object = object;
|
||||
|
||||
return iterator;
|
||||
return (zend_object_iterator *) iterator;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -683,10 +746,8 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
|
||||
zend_ce_generator->iterator_funcs.funcs = &zend_generator_iterator_functions;
|
||||
|
||||
memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
zend_generator_handlers.free_obj = zend_generator_free_storage;
|
||||
zend_generator_handlers.dtor_obj = zend_generator_dtor_storage;
|
||||
zend_generator_handlers.clone_obj = NULL;
|
||||
zend_generator_handlers.get_constructor = zend_generator_get_constructor;
|
||||
zend_generator_handlers.clone_obj = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+14
-6
@@ -25,10 +25,18 @@ BEGIN_EXTERN_C()
|
||||
|
||||
extern ZEND_API zend_class_entry *zend_ce_generator;
|
||||
|
||||
typedef struct _zend_generator_iterator {
|
||||
zend_object_iterator intern;
|
||||
|
||||
/* The generator object zval has to be stored, because the iterator is
|
||||
* holding a ref to it, which has to be dtored. */
|
||||
zval *object;
|
||||
} zend_generator_iterator;
|
||||
|
||||
typedef struct _zend_generator {
|
||||
zend_object std;
|
||||
|
||||
zend_object_iterator *iterator;
|
||||
zend_generator_iterator iterator;
|
||||
|
||||
/* The suspended execution context. */
|
||||
zend_execute_data *execute_data;
|
||||
@@ -37,13 +45,13 @@ typedef struct _zend_generator {
|
||||
zend_vm_stack stack;
|
||||
|
||||
/* Current value */
|
||||
zval value;
|
||||
zval *value;
|
||||
/* Current key */
|
||||
zval key;
|
||||
zval *key;
|
||||
/* Variable to put sent value into */
|
||||
zval *send_target;
|
||||
zval **send_target;
|
||||
/* Largest used integer key for auto-incrementing keys */
|
||||
zend_long largest_used_integer_key;
|
||||
long largest_used_integer_key;
|
||||
|
||||
/* ZEND_GENERATOR_* flags */
|
||||
zend_uchar flags;
|
||||
@@ -54,7 +62,7 @@ static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE = 0x2;
|
||||
static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
|
||||
|
||||
void zend_register_generator_ce(TSRMLS_D);
|
||||
ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC);
|
||||
ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
|
||||
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
|
||||
ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC);
|
||||
|
||||
|
||||
+43
-31
@@ -36,7 +36,6 @@
|
||||
#include "zend_modules.h"
|
||||
#include "zend_float.h"
|
||||
#include "zend_multibyte.h"
|
||||
#include "zend_arena.h"
|
||||
|
||||
/* Define ZTS if you want a thread-safe Zend */
|
||||
/*#undef ZTS*/
|
||||
@@ -86,7 +85,7 @@ struct _zend_compiler_globals {
|
||||
|
||||
zend_stack function_call_stack;
|
||||
|
||||
zend_string *compiled_filename;
|
||||
char *compiled_filename;
|
||||
|
||||
int zend_lineno;
|
||||
|
||||
@@ -112,24 +111,25 @@ struct _zend_compiler_globals {
|
||||
|
||||
zend_llist open_files;
|
||||
|
||||
zend_long catch_begin;
|
||||
long catch_begin;
|
||||
|
||||
struct _zend_ini_parser_param *ini_parser_param;
|
||||
|
||||
int interactive;
|
||||
|
||||
uint32_t start_lineno;
|
||||
zend_uint start_lineno;
|
||||
zend_bool increment_lineno;
|
||||
|
||||
znode implementing_class;
|
||||
|
||||
uint32_t access_type;
|
||||
zend_uint access_type;
|
||||
|
||||
zend_string *doc_comment;
|
||||
char *doc_comment;
|
||||
zend_uint doc_comment_len;
|
||||
|
||||
uint32_t compiler_options; /* set of ZEND_COMPILE_* constants */
|
||||
zend_uint compiler_options; /* set of ZEND_COMPILE_* constants */
|
||||
|
||||
zval current_namespace;
|
||||
zval *current_namespace;
|
||||
HashTable *current_import;
|
||||
HashTable *current_import_function;
|
||||
HashTable *current_import_const;
|
||||
@@ -141,10 +141,14 @@ struct _zend_compiler_globals {
|
||||
zend_compiler_context context;
|
||||
zend_stack context_stack;
|
||||
|
||||
zend_arena *arena;
|
||||
|
||||
zend_string *empty_string;
|
||||
zend_string *one_char_string[256];
|
||||
/* interned strings */
|
||||
char *interned_strings_start;
|
||||
char *interned_strings_end;
|
||||
char *interned_strings_top;
|
||||
char *interned_strings_snapshot_top;
|
||||
#ifndef ZTS
|
||||
char *interned_empty_string;
|
||||
#endif
|
||||
|
||||
HashTable interned_strings;
|
||||
|
||||
@@ -155,22 +159,30 @@ struct _zend_compiler_globals {
|
||||
zend_bool encoding_declared;
|
||||
|
||||
#ifdef ZTS
|
||||
zval **static_members_table;
|
||||
zval ***static_members_table;
|
||||
int last_static_member;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct _zend_executor_globals {
|
||||
zval **return_value_ptr_ptr;
|
||||
|
||||
zval uninitialized_zval;
|
||||
zval *uninitialized_zval_ptr;
|
||||
|
||||
zval error_zval;
|
||||
zval *error_zval_ptr;
|
||||
|
||||
/* symbol table cache */
|
||||
zend_array *symtable_cache[SYMTABLE_CACHE_SIZE];
|
||||
zend_array **symtable_cache_limit;
|
||||
zend_array **symtable_cache_ptr;
|
||||
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
|
||||
HashTable **symtable_cache_limit;
|
||||
HashTable **symtable_cache_ptr;
|
||||
|
||||
zend_array symbol_table; /* main symbol table */
|
||||
zend_op **opline_ptr;
|
||||
|
||||
HashTable *active_symbol_table;
|
||||
HashTable symbol_table; /* main symbol table */
|
||||
|
||||
HashTable included_files; /* files already included */
|
||||
|
||||
@@ -180,18 +192,22 @@ struct _zend_executor_globals {
|
||||
int orig_error_reporting;
|
||||
int exit_status;
|
||||
|
||||
zend_op_array *active_op_array;
|
||||
|
||||
HashTable *function_table; /* function symbol table */
|
||||
HashTable *class_table; /* class table */
|
||||
HashTable *zend_constants; /* constants table */
|
||||
|
||||
zend_class_entry *scope;
|
||||
zend_class_entry *called_scope; /* Scope of the calling class */
|
||||
|
||||
zval This;
|
||||
zval *This;
|
||||
|
||||
zend_long precision;
|
||||
long precision;
|
||||
|
||||
int ticks_count;
|
||||
|
||||
zend_bool in_execution;
|
||||
HashTable *in_autoload;
|
||||
zend_function *autoload_func;
|
||||
zend_bool full_tables_cleanup;
|
||||
@@ -210,17 +226,17 @@ struct _zend_executor_globals {
|
||||
zend_vm_stack argument_stack;
|
||||
|
||||
int user_error_handler_error_reporting;
|
||||
zval user_error_handler;
|
||||
zval user_exception_handler;
|
||||
zval *user_error_handler;
|
||||
zval *user_exception_handler;
|
||||
zend_stack user_error_handlers_error_reporting;
|
||||
zend_stack user_error_handlers;
|
||||
zend_stack user_exception_handlers;
|
||||
zend_ptr_stack user_error_handlers;
|
||||
zend_ptr_stack user_exception_handlers;
|
||||
|
||||
zend_error_handling_t error_handling;
|
||||
zend_class_entry *exception_class;
|
||||
|
||||
/* timeout support */
|
||||
zend_long timeout_seconds;
|
||||
int timeout_seconds;
|
||||
|
||||
int lambda_count;
|
||||
|
||||
@@ -229,7 +245,7 @@ struct _zend_executor_globals {
|
||||
zend_ini_entry *error_reporting_ini_entry;
|
||||
|
||||
zend_objects_store objects_store;
|
||||
zend_object *exception, *prev_exception;
|
||||
zval *exception, *prev_exception;
|
||||
zend_op *opline_before_exception;
|
||||
zend_op exception_op[3];
|
||||
|
||||
@@ -239,8 +255,7 @@ struct _zend_executor_globals {
|
||||
|
||||
zend_property_info std_property_info;
|
||||
|
||||
zend_bool active;
|
||||
zend_bool valid_symbol_table;
|
||||
zend_bool active;
|
||||
|
||||
zend_op *start_op;
|
||||
|
||||
@@ -268,7 +283,7 @@ struct _zend_ini_scanner_globals {
|
||||
char *filename;
|
||||
int lineno;
|
||||
|
||||
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */
|
||||
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */
|
||||
int scanner_mode;
|
||||
};
|
||||
|
||||
@@ -298,9 +313,6 @@ struct _zend_php_scanner_globals {
|
||||
zend_encoding_filter input_filter;
|
||||
zend_encoding_filter output_filter;
|
||||
const zend_encoding *script_encoding;
|
||||
|
||||
/* initial string length after scanning to first variable */
|
||||
int scanned_string_len;
|
||||
};
|
||||
|
||||
#endif /* ZEND_GLOBALS_H */
|
||||
|
||||
+946
-1259
File diff suppressed because it is too large.
Load diff
+243
-622
@@ -30,103 +30,109 @@
|
||||
#define HASH_KEY_NON_EXISTENT 3
|
||||
#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */
|
||||
|
||||
#define HASH_UPDATE (1<<0)
|
||||
#define HASH_ADD (1<<1)
|
||||
#define HASH_NEXT_INSERT (1<<2)
|
||||
#define HASH_UPDATE_INDIRECT (1<<3)
|
||||
#define HASH_ADD_NEW (1<<4)
|
||||
#define HASH_UPDATE (1<<0)
|
||||
#define HASH_ADD (1<<1)
|
||||
#define HASH_NEXT_INSERT (1<<2)
|
||||
|
||||
#define INVALID_IDX ((uint)-1)
|
||||
#define HASH_DEL_KEY 0
|
||||
#define HASH_DEL_INDEX 1
|
||||
#define HASH_DEL_KEY_QUICK 2
|
||||
|
||||
#define HASH_FLAG_PERSISTENT (1<<0)
|
||||
#define HASH_FLAG_APPLY_PROTECTION (1<<1)
|
||||
#define HASH_FLAG_PACKED (1<<2)
|
||||
#define HASH_UPDATE_KEY_IF_NONE 0
|
||||
#define HASH_UPDATE_KEY_IF_BEFORE 1
|
||||
#define HASH_UPDATE_KEY_IF_AFTER 2
|
||||
#define HASH_UPDATE_KEY_ANYWAY 3
|
||||
|
||||
typedef ulong (*hash_func_t)(const char *arKey, uint nKeyLength);
|
||||
typedef int (*compare_func_t)(const void *, const void * TSRMLS_DC);
|
||||
typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
|
||||
typedef void (*dtor_func_t)(void *pDest);
|
||||
typedef void (*copy_ctor_func_t)(void *pElement);
|
||||
typedef void (*copy_ctor_param_func_t)(void *pElement, void *pParam);
|
||||
|
||||
struct _hashtable;
|
||||
|
||||
typedef struct bucket {
|
||||
ulong h; /* Used for numeric indexing */
|
||||
uint nKeyLength;
|
||||
void *pData;
|
||||
void *pDataPtr;
|
||||
struct bucket *pListNext;
|
||||
struct bucket *pListLast;
|
||||
struct bucket *pNext;
|
||||
struct bucket *pLast;
|
||||
const char *arKey;
|
||||
} Bucket;
|
||||
|
||||
typedef struct _hashtable {
|
||||
uint nTableSize;
|
||||
uint nTableMask;
|
||||
uint nNumOfElements;
|
||||
ulong nNextFreeElement;
|
||||
Bucket *pInternalPointer; /* Used for element traversal */
|
||||
Bucket *pListHead;
|
||||
Bucket *pListTail;
|
||||
Bucket **arBuckets;
|
||||
dtor_func_t pDestructor;
|
||||
zend_bool persistent;
|
||||
unsigned char nApplyCount;
|
||||
zend_bool bApplyProtection;
|
||||
#if ZEND_DEBUG
|
||||
int inconsistent;
|
||||
#endif
|
||||
} HashTable;
|
||||
|
||||
#define HASH_MASK_CONSISTENCY 0x60
|
||||
|
||||
typedef struct _zend_hash_key {
|
||||
zend_ulong h;
|
||||
zend_string *key;
|
||||
const char *arKey;
|
||||
uint nKeyLength;
|
||||
ulong h;
|
||||
} zend_hash_key;
|
||||
|
||||
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
|
||||
|
||||
typedef uint HashPosition;
|
||||
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam);
|
||||
|
||||
typedef Bucket* HashPosition;
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
/* startup/shutdown */
|
||||
ZEND_API void _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
|
||||
ZEND_API void _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_hash_destroy(HashTable *ht);
|
||||
ZEND_API void zend_hash_clean(HashTable *ht);
|
||||
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API void zend_hash_real_init(HashTable *ht, int packed);
|
||||
ZEND_API void zend_hash_packed_to_hash(HashTable *ht);
|
||||
ZEND_API void zend_hash_to_packed(HashTable *ht);
|
||||
|
||||
/* additions/updates/changes */
|
||||
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_update(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_update_ind(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_add(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_add_new(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
|
||||
#define zend_hash_update(ht, key, pData) \
|
||||
_zend_hash_update(ht, key, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_update_ind(ht, key, pData) \
|
||||
_zend_hash_update_ind(ht, key, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_add(ht, key, pData) \
|
||||
_zend_hash_add(ht, key, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_add_new(ht, key, pData) \
|
||||
_zend_hash_add_new(ht, key, pData ZEND_FILE_LINE_CC)
|
||||
ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, int len, zval *pData, int flag ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
|
||||
_zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \
|
||||
_zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
|
||||
|
||||
#define zend_hash_str_update(ht, key, len, pData) \
|
||||
_zend_hash_str_update(ht, key, len, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_str_update_ind(ht, key, len, pData) \
|
||||
_zend_hash_str_update_ind(ht, key, len, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_str_add(ht, key, len, pData) \
|
||||
_zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_str_add_new(ht, key, len, pData) \
|
||||
_zend_hash_str_add_new(ht, key, len, pData ZEND_FILE_LINE_CC)
|
||||
ZEND_API int zend_hash_add_empty_element(HashTable *ht, const char *arKey, uint nKeyLength);
|
||||
|
||||
ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC);
|
||||
ZEND_API zval *_zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_FILE_LINE_DC);
|
||||
|
||||
#define zend_hash_index_add(ht, h, pData) \
|
||||
_zend_hash_index_add(ht, h, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_index_add_new(ht, h, pData) \
|
||||
_zend_hash_index_add_new(ht, h, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_index_update(ht, h, pData) \
|
||||
_zend_hash_index_update(ht, h, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_next_index_insert(ht, pData) \
|
||||
_zend_hash_next_index_insert(ht, pData ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_next_index_insert_new(ht, pData) \
|
||||
_zend_hash_next_index_insert_new(ht, pData ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API zval *zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h);
|
||||
ZEND_API zval *zend_hash_add_empty_element(HashTable *ht, zend_string *key);
|
||||
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *key, int len);
|
||||
|
||||
#define ZEND_HASH_APPLY_KEEP 0
|
||||
#define ZEND_HASH_APPLY_REMOVE 1<<0
|
||||
#define ZEND_HASH_APPLY_STOP 1<<1
|
||||
|
||||
typedef int (*apply_func_t)(zval *pDest TSRMLS_DC);
|
||||
typedef int (*apply_func_arg_t)(zval *pDest, void *argument TSRMLS_DC);
|
||||
typedef int (*apply_func_args_t)(zval *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
|
||||
typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
|
||||
typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
|
||||
typedef int (*apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
|
||||
|
||||
ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
|
||||
ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht);
|
||||
@@ -144,82 +150,153 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
|
||||
|
||||
|
||||
/* Deletes */
|
||||
ZEND_API int zend_hash_del(HashTable *ht, zend_string *key);
|
||||
ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key);
|
||||
ZEND_API int zend_hash_str_del(HashTable *ht, const char *key, int len);
|
||||
ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *key, int len);
|
||||
ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h);
|
||||
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag);
|
||||
#define zend_hash_del(ht, arKey, nKeyLength) \
|
||||
zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
|
||||
#define zend_hash_quick_del(ht, arKey, nKeyLength, h) \
|
||||
zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
|
||||
#define zend_hash_index_del(ht, h) \
|
||||
zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
|
||||
#define zend_get_hash_value \
|
||||
zend_hash_func
|
||||
|
||||
/* Data retreival */
|
||||
ZEND_API zval *zend_hash_find(const HashTable *ht, zend_string *key);
|
||||
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *key, int len);
|
||||
ZEND_API zval *zend_hash_index_find(const HashTable *ht, zend_ulong h);
|
||||
ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData);
|
||||
ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData);
|
||||
|
||||
/* Misc */
|
||||
ZEND_API int zend_hash_exists(const HashTable *ht, zend_string *key);
|
||||
ZEND_API int zend_hash_str_exists(const HashTable *ht, const char *str, int len);
|
||||
ZEND_API int zend_hash_index_exists(const HashTable *ht, zend_ulong h);
|
||||
ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h);
|
||||
ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
|
||||
ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
|
||||
|
||||
/* traversing */
|
||||
#define zend_hash_has_more_elements_ex(ht, pos) \
|
||||
(zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
|
||||
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, zend_bool duplicate, HashPosition *pos);
|
||||
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
|
||||
ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
|
||||
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
|
||||
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
|
||||
|
||||
typedef struct _HashPointer {
|
||||
HashPosition pos;
|
||||
HashTable *ht;
|
||||
zend_ulong h;
|
||||
ulong h;
|
||||
} HashPointer;
|
||||
|
||||
ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr);
|
||||
ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
|
||||
|
||||
#define zend_hash_has_more_elements(ht) \
|
||||
zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_has_more_elements_ex(ht, NULL)
|
||||
#define zend_hash_move_forward(ht) \
|
||||
zend_hash_move_forward_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_move_forward_ex(ht, NULL)
|
||||
#define zend_hash_move_backwards(ht) \
|
||||
zend_hash_move_backwards_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_move_backwards_ex(ht, NULL)
|
||||
#define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
|
||||
zend_hash_get_current_key_ex(ht, str_index, num_index, duplicate, &(ht)->nInternalPointer)
|
||||
zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
|
||||
#define zend_hash_get_current_key_zval(ht, key) \
|
||||
zend_hash_get_current_key_zval_ex(ht, key, &(ht)->nInternalPointer)
|
||||
zend_hash_get_current_key_zval_ex(ht, key, NULL)
|
||||
#define zend_hash_get_current_key_type(ht) \
|
||||
zend_hash_get_current_key_type_ex(ht, &(ht)->nInternalPointer)
|
||||
#define zend_hash_get_current_data(ht) \
|
||||
zend_hash_get_current_data_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_get_current_key_type_ex(ht, NULL)
|
||||
#define zend_hash_get_current_data(ht, pData) \
|
||||
zend_hash_get_current_data_ex(ht, pData, NULL)
|
||||
#define zend_hash_internal_pointer_reset(ht) \
|
||||
zend_hash_internal_pointer_reset_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_internal_pointer_reset_ex(ht, NULL)
|
||||
#define zend_hash_internal_pointer_end(ht) \
|
||||
zend_hash_internal_pointer_end_ex(ht, &(ht)->nInternalPointer)
|
||||
zend_hash_internal_pointer_end_ex(ht, NULL)
|
||||
#define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index) \
|
||||
zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
|
||||
|
||||
/* Copying, merging and sorting */
|
||||
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor);
|
||||
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam);
|
||||
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
|
||||
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
|
||||
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
|
||||
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
|
||||
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag TSRMLS_DC);
|
||||
ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);
|
||||
|
||||
#define zend_hash_merge(target, source, pCopyConstructor, overwrite) \
|
||||
_zend_hash_merge(target, source, pCopyConstructor, overwrite ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite) \
|
||||
_zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)
|
||||
|
||||
#define zend_hash_num_elements(ht) \
|
||||
(ht)->nNumOfElements
|
||||
|
||||
#define zend_hash_next_free_element(ht) \
|
||||
(ht)->nNextFreeElement
|
||||
ZEND_API int zend_hash_num_elements(const HashTable *ht);
|
||||
|
||||
ZEND_API int zend_hash_rehash(HashTable *ht);
|
||||
ZEND_API void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
|
||||
|
||||
ZEND_API void zend_array_dup(HashTable *target, HashTable *source);
|
||||
ZEND_API void _zend_hash_splice(HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor, uint offset, uint length, void **list, uint list_count, HashTable *removed ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_splice(ht, nDataSize, pCopyConstructor, offset, length, list, list_count, removed) \
|
||||
_zend_hash_splice(ht, nDataSize, pCopyConstructor, offset, length, list, list_count, removed ZEND_FILE_LINE_CC)
|
||||
|
||||
/*
|
||||
* DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
|
||||
*
|
||||
* This is Daniel J. Bernstein's popular `times 33' hash function as
|
||||
* posted by him years ago on comp.lang.c. It basically uses a function
|
||||
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
|
||||
* known hash functions for strings. Because it is both computed very
|
||||
* fast and distributes very well.
|
||||
*
|
||||
* The magic of number 33, i.e. why it works better than many other
|
||||
* constants, prime or not, has never been adequately explained by
|
||||
* anyone. So I try an explanation: if one experimentally tests all
|
||||
* multipliers between 1 and 256 (as RSE did now) one detects that even
|
||||
* numbers are not useable at all. The remaining 128 odd numbers
|
||||
* (except for the number 1) work more or less all equally well. They
|
||||
* all distribute in an acceptable way and this way fill a hash table
|
||||
* with an average percent of approx. 86%.
|
||||
*
|
||||
* If one compares the Chi^2 values of the variants, the number 33 not
|
||||
* even has the best value. But the number 33 and a few other equally
|
||||
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
|
||||
* advantage to the remaining numbers in the large set of possible
|
||||
* multipliers: their multiply operation can be replaced by a faster
|
||||
* operation based on just one shift plus either a single addition
|
||||
* or subtraction operation. And because a hash function has to both
|
||||
* distribute good _and_ has to be very fast to compute, those few
|
||||
* numbers should be preferred and seems to be the reason why Daniel J.
|
||||
* Bernstein also preferred it.
|
||||
*
|
||||
*
|
||||
* -- Ralf S. Engelschall <rse@engelschall.com>
|
||||
*/
|
||||
|
||||
static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
|
||||
{
|
||||
register ulong hash = 5381;
|
||||
|
||||
/* variant with the hash unrolled eight times */
|
||||
for (; nKeyLength >= 8; nKeyLength -= 8) {
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
hash = ((hash << 5) + hash) + *arKey++;
|
||||
}
|
||||
switch (nKeyLength) {
|
||||
case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
|
||||
case 1: hash = ((hash << 5) + hash) + *arKey++; break;
|
||||
case 0: break;
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* debug */
|
||||
@@ -230,544 +307,88 @@ void zend_hash_display(const HashTable *ht);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_INIT_SYMTABLE(ht) \
|
||||
ZEND_INIT_SYMTABLE_EX(ht, 8, 0)
|
||||
ZEND_INIT_SYMTABLE_EX(ht, 2, 0)
|
||||
|
||||
#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \
|
||||
zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
|
||||
|
||||
static inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx)
|
||||
#define ZEND_HANDLE_NUMERIC_EX(key, length, idx, func) do { \
|
||||
register const char *tmp = key; \
|
||||
\
|
||||
if (*tmp == '-') { \
|
||||
tmp++; \
|
||||
} \
|
||||
if (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */ \
|
||||
const char *end = key + length - 1; \
|
||||
\
|
||||
if ((*end != '\0') /* not a null terminated string */ \
|
||||
|| (*tmp == '0' && length > 2) /* numbers with leading zeros */ \
|
||||
|| (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */ \
|
||||
|| (SIZEOF_LONG == 4 && \
|
||||
end - tmp == MAX_LENGTH_OF_LONG - 1 && \
|
||||
*tmp > '2')) { /* overflow */ \
|
||||
break; \
|
||||
} \
|
||||
idx = (*tmp - '0'); \
|
||||
while (++tmp != end && *tmp >= '0' && *tmp <= '9') { \
|
||||
idx = (idx * 10) + (*tmp - '0'); \
|
||||
} \
|
||||
if (tmp == end) { \
|
||||
if (*key == '-') { \
|
||||
if (idx-1 > LONG_MAX) { /* overflow */ \
|
||||
break; \
|
||||
} \
|
||||
idx = 0 - idx; \
|
||||
} else if (idx > LONG_MAX) { /* overflow */ \
|
||||
break; \
|
||||
} \
|
||||
func; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ZEND_HANDLE_NUMERIC(key, length, func) do { \
|
||||
ulong idx; \
|
||||
\
|
||||
ZEND_HANDLE_NUMERIC_EX(key, length, idx, return func); \
|
||||
} while (0)
|
||||
|
||||
static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \
|
||||
{
|
||||
register const char *tmp = key;
|
||||
const char *end;
|
||||
|
||||
if (*tmp > '9') {
|
||||
return 0;
|
||||
} else if (*tmp < '0') {
|
||||
if (*tmp != '-') {
|
||||
return 0;
|
||||
}
|
||||
tmp++;
|
||||
if (*tmp > '9' || *tmp < '0') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* possibly a numeric index */
|
||||
end = key + length;
|
||||
|
||||
if ((*end != '\0') /* not a null terminated string */
|
||||
|| (*tmp == '0' && length > 1) /* numbers with leading zeros */
|
||||
|| (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */
|
||||
|| (SIZEOF_ZEND_LONG == 4 &&
|
||||
end - tmp == MAX_LENGTH_OF_LONG - 1 &&
|
||||
*tmp > '2')) { /* overflow */
|
||||
return 0;
|
||||
}
|
||||
*idx = (*tmp - '0');
|
||||
while (1) {
|
||||
++tmp;
|
||||
if (tmp == end) {
|
||||
if (*key == '-') {
|
||||
if (*idx-1 > ZEND_LONG_MAX) { /* overflow */
|
||||
return 0;
|
||||
}
|
||||
*idx = 0 - *idx;
|
||||
} else if (*idx > ZEND_LONG_MAX) { /* overflow */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (*tmp <= '9' && *tmp >= '0') {
|
||||
*idx = (*idx * 10) + (*tmp - '0');
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ZEND_HANDLE_NUMERIC_STR(key, length, idx) \
|
||||
_zend_handle_numeric_str(key, length, &idx)
|
||||
|
||||
#define ZEND_HANDLE_NUMERIC(key, idx) \
|
||||
_zend_handle_numeric_str((key)->val, (key)->len, &idx)
|
||||
|
||||
|
||||
static inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_find(ht, key);
|
||||
return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? Z_INDIRECT_P(zv) : zv;
|
||||
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
|
||||
return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key)
|
||||
static inline int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_find(ht, key);
|
||||
return zv && (Z_TYPE_P(zv) != IS_INDIRECT ||
|
||||
Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF);
|
||||
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx));
|
||||
return zend_hash_del(ht, arKey, nKeyLength);
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str, int len)
|
||||
static inline int zend_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_str_find(ht, str, len);
|
||||
return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? Z_INDIRECT_P(zv) : zv;
|
||||
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
|
||||
return zend_hash_find(ht, arKey, nKeyLength, pData);
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
|
||||
static inline int zend_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_update(ht, idx, pData);
|
||||
} else {
|
||||
return zend_hash_update(ht, key, pData);
|
||||
}
|
||||
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
|
||||
return zend_hash_exists(ht, arKey, nKeyLength);
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zval *pData)
|
||||
static inline int zend_symtable_update_current_key_ex(HashTable *ht, const char *arKey, uint nKeyLength, int mode, HashPosition *pos)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_update(ht, idx, pData);
|
||||
} else {
|
||||
return zend_hash_update_ind(ht, key, pData);
|
||||
}
|
||||
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, 0, idx, mode, pos));
|
||||
return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0, mode, pos);
|
||||
}
|
||||
#define zend_symtable_update_current_key(ht,arKey,nKeyLength,mode) \
|
||||
zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)
|
||||
|
||||
|
||||
static inline int zend_symtable_del(HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_del(ht, idx);
|
||||
} else {
|
||||
return zend_hash_del(ht, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_del(ht, idx);
|
||||
} else {
|
||||
return zend_hash_del_ind(ht, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_find(ht, idx);
|
||||
} else {
|
||||
return zend_hash_find(ht, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_find(ht, idx);
|
||||
} else {
|
||||
return zend_hash_find_ind(ht, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_exists(HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_exists(ht, idx);
|
||||
} else {
|
||||
return zend_hash_exists(ht, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int len, zval *pData)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_update(ht, idx, pData);
|
||||
} else {
|
||||
return zend_hash_str_update(ht, str, len, pData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str, int len, zval *pData)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_update(ht, idx, pData);
|
||||
} else {
|
||||
return zend_hash_str_update_ind(ht, str, len, pData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_del(ht, idx);
|
||||
} else {
|
||||
return zend_hash_str_del(ht, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_del(ht, idx);
|
||||
} else {
|
||||
return zend_hash_str_del_ind(ht, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_find(ht, idx);
|
||||
} else {
|
||||
return zend_hash_str_find(ht, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_str_exists(HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_exists(ht, idx);
|
||||
} else {
|
||||
return zend_hash_str_exists(ht, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_add(ht, key, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string *key, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_add_new(ht, key, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, int len, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_str_add(ht, str, len, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_update(ht, key, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, int len, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_str_update(ht, str, len, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, NULL);
|
||||
if ((zv = zend_hash_add(ht, key, &tmp))) {
|
||||
Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(Z_PTR_P(zv), pData, size);
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, NULL);
|
||||
if ((zv = zend_hash_str_add(ht, str, len, &tmp))) {
|
||||
Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(Z_PTR_P(zv), pData, size);
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(p, pData, size);
|
||||
return zend_hash_update_ptr(ht, key, p);
|
||||
}
|
||||
|
||||
static inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(p, pData, size);
|
||||
return zend_hash_str_update_ptr(ht, str, len, p);
|
||||
}
|
||||
|
||||
static inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_index_update(ht, h, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_next_index_insert(ht, &tmp);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_index_update_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(p, pData, size);
|
||||
return zend_hash_index_update_ptr(ht, h, p);
|
||||
}
|
||||
|
||||
static inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
|
||||
{
|
||||
zval tmp, *zv;
|
||||
|
||||
ZVAL_PTR(&tmp, NULL);
|
||||
if ((zv = zend_hash_next_index_insert(ht, &tmp))) {
|
||||
Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
memcpy(Z_PTR_P(zv), pData, size);
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_find(ht, key);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_str_find(ht, str, len);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_index_find(ht, h);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
static inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, int len)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
|
||||
return zend_hash_index_find_ptr(ht, idx);
|
||||
} else {
|
||||
return zend_hash_str_find_ptr(ht, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
zval *zv;
|
||||
|
||||
zv = zend_hash_get_current_data_ex(ht, pos);
|
||||
return zv ? Z_PTR_P(zv) : NULL;
|
||||
}
|
||||
|
||||
#define zend_hash_get_current_data_ptr(ht) \
|
||||
zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
|
||||
|
||||
#define ZEND_HASH_FOREACH(_ht, indirect) do { \
|
||||
uint _idx; \
|
||||
for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
|
||||
Bucket *_p = (_ht)->arData + _idx; \
|
||||
zval *_z = &_p->val; \
|
||||
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
_z = Z_INDIRECT_P(_z); \
|
||||
} \
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
|
||||
uint _idx; \
|
||||
for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
|
||||
Bucket *_p = (_ht)->arData + _idx - 1; \
|
||||
zval *_z = &_p->val; \
|
||||
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
|
||||
_z = Z_INDIRECT_P(_z); \
|
||||
} \
|
||||
if (Z_TYPE_P(_z) == IS_UNDEF) continue;
|
||||
|
||||
#define ZEND_HASH_FOREACH_END() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ZEND_HASH_FOREACH_BUCKET(ht, _bucket) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_bucket = _p;
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL(ht, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_VAL_IND(ht, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 1); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_PTR(ht, _ptr) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_FOREACH_NUM_KEY(ht, _h) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h;
|
||||
|
||||
#define ZEND_HASH_FOREACH_STR_KEY(ht, _key) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_key = _p->key;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY(ht, _h, _key) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key;
|
||||
|
||||
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 1); \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
|
||||
ZEND_HASH_FOREACH(ht, 1); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_key = _p->key; \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
|
||||
ZEND_HASH_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_PTR(ht, _ptr) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
|
||||
_ptr = Z_PTR_P(_z);
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 1); \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
|
||||
ZEND_HASH_REVERSE_FOREACH(ht, 1); \
|
||||
_h = _p->h; \
|
||||
_key = _p->key; \
|
||||
_val = _z;
|
||||
|
||||
#define ZEND_HASH_APPLY_PROTECTION(ht) \
|
||||
((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION)
|
||||
|
||||
#define ZEND_HASH_APPLY_SHIFT 8
|
||||
#define ZEND_HASH_GET_APPLY_COUNT(ht) ((ht)->u.flags >> ZEND_HASH_APPLY_SHIFT)
|
||||
#define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->u.flags += (1 << ZEND_HASH_APPLY_SHIFT))
|
||||
#define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->u.flags -= (1 << ZEND_HASH_APPLY_SHIFT))
|
||||
|
||||
#endif /* ZEND_HASH_H */
|
||||
|
||||
/*
|
||||
|
||||
+12
-13
@@ -92,7 +92,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
zend_printf("<code>");
|
||||
zend_printf("<span style=\"color: %s\">\n", last_color);
|
||||
/* highlight stuff coming back from zendlex() */
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token TSRMLS_CC))) {
|
||||
switch (token_type) {
|
||||
case T_INLINE_HTML:
|
||||
@@ -116,11 +116,11 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
break;
|
||||
case T_WHITESPACE:
|
||||
zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC); /* no color needed */
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (Z_TYPE(token) == IS_UNDEF) {
|
||||
if (token.type == 0) {
|
||||
next_color = syntax_highlighter_ini->highlight_keyword;
|
||||
} else {
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
@@ -140,7 +140,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
|
||||
zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE(token) == IS_STRING) {
|
||||
if (token.type == IS_STRING) {
|
||||
switch (token_type) {
|
||||
case T_OPEN_TAG:
|
||||
case T_OPEN_TAG_WITH_ECHO:
|
||||
@@ -150,11 +150,11 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
case T_DOC_COMMENT:
|
||||
break;
|
||||
default:
|
||||
zend_string_release(Z_STR(token));
|
||||
str_efree(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
}
|
||||
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
@@ -170,7 +170,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
int token_type;
|
||||
int prev_space = 0;
|
||||
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token TSRMLS_CC))) {
|
||||
switch (token_type) {
|
||||
case T_WHITESPACE:
|
||||
@@ -181,7 +181,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
/* lack of break; is intentional */
|
||||
case T_COMMENT:
|
||||
case T_DOC_COMMENT:
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
continue;
|
||||
|
||||
case T_END_HEREDOC:
|
||||
@@ -192,7 +192,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
}
|
||||
zend_write("\n", sizeof("\n") - 1);
|
||||
prev_space = 1;
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
continue;
|
||||
|
||||
default:
|
||||
@@ -200,7 +200,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Z_TYPE(token) == IS_STRING) {
|
||||
if (token.type == IS_STRING) {
|
||||
switch (token_type) {
|
||||
case T_OPEN_TAG:
|
||||
case T_OPEN_TAG_WITH_ECHO:
|
||||
@@ -211,12 +211,11 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
break;
|
||||
|
||||
default:
|
||||
zend_string_release(Z_STR(token));
|
||||
STR_FREE(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev_space = 0;
|
||||
ZVAL_UNDEF(&token);
|
||||
prev_space = token.type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -47,7 +47,7 @@ static void handle_whitespace(int *emit_whitespace)
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_indent(TSRMLS_D)
|
||||
ZEND_API void zend_indent()
|
||||
{
|
||||
zval token;
|
||||
int token_type;
|
||||
@@ -55,18 +55,19 @@ ZEND_API void zend_indent(TSRMLS_D)
|
||||
int nest_level=0;
|
||||
int emit_whitespace[256];
|
||||
int i;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
memset(emit_whitespace, 0, sizeof(int)*256);
|
||||
|
||||
/* highlight stuff coming back from zendlex() */
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token TSRMLS_CC))) {
|
||||
switch (token_type) {
|
||||
case T_INLINE_HTML:
|
||||
zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
|
||||
break;
|
||||
case T_WHITESPACE: {
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
/* eat whitespace, emit newlines */
|
||||
for (i=0; i<LANG_SCNG(yy_leng); i++) {
|
||||
emit_whitespace[(unsigned char) LANG_SCNG(yy_text)[i]]++;
|
||||
@@ -78,7 +79,7 @@ ZEND_API void zend_indent(TSRMLS_D)
|
||||
in_string = !in_string;
|
||||
/* break missing intentionally */
|
||||
default:
|
||||
if (Z_TYPE(token) == IS_UNDEF) {
|
||||
if (token.type==0) {
|
||||
/* keyword */
|
||||
switch (token_type) {
|
||||
case ',':
|
||||
@@ -131,18 +132,18 @@ dflt_printout:
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Z_TYPE(token) == IS_STRING) {
|
||||
if (token.type == IS_STRING) {
|
||||
switch (token_type) {
|
||||
case T_OPEN_TAG:
|
||||
case T_CLOSE_TAG:
|
||||
case T_WHITESPACE:
|
||||
break;
|
||||
default:
|
||||
zend_string_release(Z_STR(token));
|
||||
str_efree(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZVAL_UNDEF(&token);
|
||||
token.type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#define ZEND_INDENT_H
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_indent(TSRMLS_D);
|
||||
ZEND_API void zend_indent(void);
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* ZEND_INDENT_H */
|
||||
|
||||
+44
-54
@@ -34,11 +34,9 @@ static HashTable *registered_zend_ini_directives;
|
||||
/*
|
||||
* hash_apply functions
|
||||
*/
|
||||
static int zend_remove_ini_entries(zval *el, void *arg TSRMLS_DC) /* {{{ */
|
||||
static int zend_remove_ini_entries(zend_ini_entry *ini_entry, int *module_number TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
|
||||
int module_number = *(int *)arg;
|
||||
if (ini_entry->module_number == module_number) {
|
||||
if (ini_entry->module_number == *module_number) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -78,20 +76,13 @@ static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage TSRMLS
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_restore_ini_entry_wrapper(zval *el TSRMLS_DC) /* {{{ */
|
||||
static int zend_restore_ini_entry_wrapper(zend_ini_entry **ini_entry TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
|
||||
zend_restore_ini_entry_cb(ini_entry, ZEND_INI_STAGE_DEACTIVATE TSRMLS_CC);
|
||||
zend_restore_ini_entry_cb(*ini_entry, ZEND_INI_STAGE_DEACTIVATE TSRMLS_CC);
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _free_ptr(zval *zv) /* {{{ */
|
||||
{
|
||||
free(Z_PTR_P(zv));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Startup / shutdown
|
||||
*/
|
||||
@@ -102,7 +93,9 @@ ZEND_API int zend_ini_startup(TSRMLS_D) /* {{{ */
|
||||
EG(ini_directives) = registered_zend_ini_directives;
|
||||
EG(modified_ini_directives) = NULL;
|
||||
EG(error_reporting_ini_entry) = NULL;
|
||||
zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, _free_ptr, 1, 0);
|
||||
if (zend_hash_init_ex(registered_zend_ini_directives, 100, NULL, NULL, 1, 0) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -126,7 +119,7 @@ ZEND_API int zend_ini_global_shutdown(TSRMLS_D) /* {{{ */
|
||||
ZEND_API int zend_ini_deactivate(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
if (EG(modified_ini_directives)) {
|
||||
zend_hash_apply(EG(modified_ini_directives), zend_restore_ini_entry_wrapper TSRMLS_CC);
|
||||
zend_hash_apply(EG(modified_ini_directives), (apply_func_t) zend_restore_ini_entry_wrapper TSRMLS_CC);
|
||||
zend_hash_destroy(EG(modified_ini_directives));
|
||||
FREE_HASHTABLE(EG(modified_ini_directives));
|
||||
EG(modified_ini_directives) = NULL;
|
||||
@@ -138,11 +131,15 @@ ZEND_API int zend_ini_deactivate(TSRMLS_D) /* {{{ */
|
||||
#ifdef ZTS
|
||||
ZEND_API int zend_copy_ini_directives(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
zend_ini_entry ini_entry;
|
||||
|
||||
EG(modified_ini_directives) = NULL;
|
||||
EG(error_reporting_ini_entry) = NULL;
|
||||
EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
|
||||
zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0);
|
||||
zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, NULL);
|
||||
if (zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, NULL, &ini_entry, sizeof(zend_ini_entry));
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -153,17 +150,17 @@ static int ini_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{ */
|
||||
const Bucket *f;
|
||||
const Bucket *s;
|
||||
|
||||
f = (const Bucket *) a;
|
||||
s = (const Bucket *) b;
|
||||
f = *((const Bucket **) a);
|
||||
s = *((const Bucket **) b);
|
||||
|
||||
if (!f->key && !s->key) { /* both numeric */
|
||||
return ZEND_NORMALIZE_BOOL(f->h - s->h);
|
||||
} else if (!f->key) { /* f is numeric, s is not */
|
||||
if (f->nKeyLength == 0 && s->nKeyLength == 0) { /* both numeric */
|
||||
return ZEND_NORMALIZE_BOOL(f->nKeyLength - s->nKeyLength);
|
||||
} else if (f->nKeyLength == 0) { /* f is numeric, s is not */
|
||||
return -1;
|
||||
} else if (!s->key) { /* s is numeric, f is not */
|
||||
} else if (s->nKeyLength == 0) { /* s is numeric, f is not */
|
||||
return 1;
|
||||
} else { /* both strings */
|
||||
return zend_binary_strcasecmp(f->key->val, f->key->len, s->key->val, s->key->len);
|
||||
return zend_binary_strcasecmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -201,7 +198,7 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int modu
|
||||
|
||||
while (p->name) {
|
||||
config_directive_success = 0;
|
||||
if ((hashed_ini_entry = zend_hash_str_add_mem(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry))) == NULL) {
|
||||
if (zend_hash_add(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry), (void **) &hashed_ini_entry) == FAILURE) {
|
||||
zend_unregister_ini_entries(module_number TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -226,16 +223,13 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int modu
|
||||
|
||||
ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_hash_apply_with_argument(registered_zend_ini_directives, zend_remove_ini_entries, (void *) &module_number TSRMLS_CC);
|
||||
zend_hash_apply_with_argument(registered_zend_ini_directives, (apply_func_arg_t) zend_remove_ini_entries, (void *) &module_number TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZTS
|
||||
static int zend_ini_refresh_cache(zval *el, void *arg TSRMLS_DC) /* {{{ */
|
||||
static int zend_ini_refresh_cache(zend_ini_entry *p, int stage TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *p = (zend_ini_entry *)Z_PTR_P(el);
|
||||
int stage = (int)(zend_intptr_t)arg;
|
||||
|
||||
if (p->on_modify) {
|
||||
p->on_modify(p, p->value, p->value_length, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage TSRMLS_CC);
|
||||
}
|
||||
@@ -245,27 +239,27 @@ static int zend_ini_refresh_cache(zval *el, void *arg TSRMLS_DC) /* {{{ */
|
||||
|
||||
ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_hash_apply_with_argument(EG(ini_directives), zend_ini_refresh_cache, (void *)(zend_intptr_t) stage TSRMLS_CC);
|
||||
zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) zend_ini_refresh_cache, (void *)(zend_intptr_t) stage TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
|
||||
ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
return zend_alter_ini_entry_ex(name, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
|
||||
return zend_alter_ini_entry_ex(name, name_length, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *ini_entry;
|
||||
char *duplicate;
|
||||
zend_bool modifiable;
|
||||
zend_bool modified;
|
||||
|
||||
if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL) {
|
||||
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -291,7 +285,7 @@ ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint ne
|
||||
ini_entry->orig_value_length = ini_entry->value_length;
|
||||
ini_entry->orig_modifiable = modifiable;
|
||||
ini_entry->modified = 1;
|
||||
zend_hash_add_ptr(EG(modified_ini_directives), name, ini_entry);
|
||||
zend_hash_add(EG(modified_ini_directives), name, name_length, &ini_entry, sizeof(zend_ini_entry*), NULL);
|
||||
}
|
||||
|
||||
duplicate = estrndup(new_value, new_value_length);
|
||||
@@ -312,19 +306,19 @@ ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint ne
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_restore_ini_entry(zend_string *name, int stage) /* {{{ */
|
||||
ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *ini_entry;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL ||
|
||||
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE ||
|
||||
(stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (EG(modified_ini_directives)) {
|
||||
if (zend_restore_ini_entry_cb(ini_entry, stage TSRMLS_CC) == 0) {
|
||||
zend_hash_del(EG(modified_ini_directives), name);
|
||||
zend_hash_del(EG(modified_ini_directives), name, name_length);
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -338,8 +332,7 @@ ZEND_API int zend_ini_register_displayer(char *name, uint name_length, void (*di
|
||||
{
|
||||
zend_ini_entry *ini_entry;
|
||||
|
||||
ini_entry = zend_hash_str_find_ptr(registered_zend_ini_directives, name, name_length);
|
||||
if (ini_entry == NULL) {
|
||||
if (zend_hash_find(registered_zend_ini_directives, name, name_length, (void **) &ini_entry) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -352,17 +345,16 @@ ZEND_API int zend_ini_register_displayer(char *name, uint name_length, void (*di
|
||||
* Data retrieval
|
||||
*/
|
||||
|
||||
ZEND_API zend_long zend_ini_long(char *name, uint name_length, int orig) /* {{{ */
|
||||
ZEND_API long zend_ini_long(char *name, uint name_length, int orig) /* {{{ */
|
||||
{
|
||||
zend_ini_entry *ini_entry;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
|
||||
if (ini_entry) {
|
||||
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
|
||||
if (orig && ini_entry->modified) {
|
||||
return (ini_entry->orig_value ? ZEND_STRTOL(ini_entry->orig_value, NULL, 0) : 0);
|
||||
return (ini_entry->orig_value ? strtol(ini_entry->orig_value, NULL, 0) : 0);
|
||||
} else {
|
||||
return (ini_entry->value ? ZEND_STRTOL(ini_entry->value, NULL, 0) : 0);
|
||||
return (ini_entry->value ? strtol(ini_entry->value, NULL, 0) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,8 +367,7 @@ ZEND_API double zend_ini_double(char *name, uint name_length, int orig) /* {{{ *
|
||||
zend_ini_entry *ini_entry;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
|
||||
if (ini_entry) {
|
||||
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
|
||||
if (orig && ini_entry->modified) {
|
||||
return (double) (ini_entry->orig_value ? zend_strtod(ini_entry->orig_value, NULL) : 0.0);
|
||||
} else {
|
||||
@@ -393,8 +384,7 @@ ZEND_API char *zend_ini_string_ex(char *name, uint name_length, int orig, zend_b
|
||||
zend_ini_entry *ini_entry;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
|
||||
if (ini_entry) {
|
||||
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
|
||||
if (exists) {
|
||||
*exists = 1;
|
||||
}
|
||||
@@ -587,7 +577,7 @@ ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
|
||||
|
||||
ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
|
||||
{
|
||||
zend_long *p;
|
||||
long *p;
|
||||
#ifndef ZTS
|
||||
char *base = (char *) mh_arg2;
|
||||
#else
|
||||
@@ -596,7 +586,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
|
||||
base = (char *) ts_resource(*((int *) mh_arg2));
|
||||
#endif
|
||||
|
||||
p = (zend_long *) (base+(size_t) mh_arg1);
|
||||
p = (long *) (base+(size_t) mh_arg1);
|
||||
|
||||
*p = zend_atol(new_value, new_value_length);
|
||||
return SUCCESS;
|
||||
@@ -605,7 +595,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
|
||||
|
||||
ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
|
||||
{
|
||||
zend_long *p, tmp;
|
||||
long *p, tmp;
|
||||
#ifndef ZTS
|
||||
char *base = (char *) mh_arg2;
|
||||
#else
|
||||
@@ -619,7 +609,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
p = (zend_long *) (base+(size_t) mh_arg1);
|
||||
p = (long *) (base+(size_t) mh_arg1);
|
||||
*p = tmp;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
+45
-15
@@ -27,23 +27,53 @@
|
||||
|
||||
#define ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM)
|
||||
|
||||
#ifndef XtOffsetOf
|
||||
# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
|
||||
# ifdef __STDC__
|
||||
# define XtOffset(p_type, field) _Offsetof(p_type, field)
|
||||
# else
|
||||
# ifdef CRAY2
|
||||
# define XtOffset(p_type, field) \
|
||||
(sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
|
||||
|
||||
# else /* !CRAY2 */
|
||||
|
||||
# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
|
||||
|
||||
# endif /* !CRAY2 */
|
||||
# endif /* __STDC__ */
|
||||
# else /* ! (CRAY || __arm) */
|
||||
|
||||
# define XtOffset(p_type, field) \
|
||||
((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
|
||||
|
||||
# endif /* !CRAY */
|
||||
|
||||
# ifdef offsetof
|
||||
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
|
||||
# else
|
||||
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
|
||||
#define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)
|
||||
|
||||
struct _zend_ini_entry {
|
||||
int module_number;
|
||||
int modifiable;
|
||||
char *name; // TODO: convert into zend_string ???
|
||||
char *name;
|
||||
uint name_length;
|
||||
ZEND_INI_MH((*on_modify));
|
||||
void *mh_arg1;
|
||||
void *mh_arg2;
|
||||
void *mh_arg3;
|
||||
|
||||
char *value; // TODO: convert into zend_string ???
|
||||
char *value;
|
||||
uint value_length;
|
||||
|
||||
char *orig_value; // TODO: convert into zend_string ???
|
||||
char *orig_value;
|
||||
uint orig_value_length;
|
||||
int orig_modifiable;
|
||||
int modified;
|
||||
@@ -64,12 +94,12 @@ ZEND_API void zend_ini_sort_entries(TSRMLS_D);
|
||||
ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC);
|
||||
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage);
|
||||
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC);
|
||||
ZEND_API int zend_restore_ini_entry(zend_string *name, int stage);
|
||||
ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage);
|
||||
ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC);
|
||||
ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage);
|
||||
ZEND_API void display_ini_entries(zend_module_entry *module);
|
||||
|
||||
ZEND_API zend_long zend_ini_long(char *name, uint name_length, int orig);
|
||||
ZEND_API long zend_ini_long(char *name, uint name_length, int orig);
|
||||
ZEND_API double zend_ini_double(char *name, uint name_length, int orig);
|
||||
ZEND_API char *zend_ini_string(char *name, uint name_length, int orig);
|
||||
ZEND_API char *zend_ini_string_ex(char *name, uint name_length, int orig, zend_bool *exists);
|
||||
@@ -85,7 +115,7 @@ END_EXTERN_C()
|
||||
#define ZEND_INI_END() { 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL } };
|
||||
|
||||
#define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \
|
||||
{ 0, modifiable, name, sizeof(name)-1, on_modify, arg1, arg2, arg3, default_value, sizeof(default_value)-1, NULL, 0, 0, 0, displayer },
|
||||
{ 0, modifiable, name, sizeof(name), on_modify, arg1, arg2, arg3, default_value, sizeof(default_value)-1, NULL, 0, 0, 0, displayer },
|
||||
|
||||
#define ZEND_INI_ENTRY3(name, default_value, modifiable, on_modify, arg1, arg2, arg3) \
|
||||
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, NULL)
|
||||
@@ -124,21 +154,21 @@ END_EXTERN_C()
|
||||
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
|
||||
#endif
|
||||
|
||||
#define INI_INT(name) zend_ini_long((name), sizeof(name)-1, 0)
|
||||
#define INI_FLT(name) zend_ini_double((name), sizeof(name)-1, 0)
|
||||
#define INI_STR(name) zend_ini_string_ex((name), sizeof(name)-1, 0, NULL)
|
||||
#define INI_INT(name) zend_ini_long((name), sizeof(name), 0)
|
||||
#define INI_FLT(name) zend_ini_double((name), sizeof(name), 0)
|
||||
#define INI_STR(name) zend_ini_string_ex((name), sizeof(name), 0, NULL)
|
||||
#define INI_BOOL(name) ((zend_bool) INI_INT(name))
|
||||
|
||||
#define INI_ORIG_INT(name) zend_ini_long((name), sizeof(name)-1, 1)
|
||||
#define INI_ORIG_FLT(name) zend_ini_double((name), sizeof(name)-1, 1)
|
||||
#define INI_ORIG_STR(name) zend_ini_string((name), sizeof(name)-1, 1)
|
||||
#define INI_ORIG_INT(name) zend_ini_long((name), sizeof(name), 1)
|
||||
#define INI_ORIG_FLT(name) zend_ini_double((name), sizeof(name), 1)
|
||||
#define INI_ORIG_STR(name) zend_ini_string((name), sizeof(name), 1)
|
||||
#define INI_ORIG_BOOL(name) ((zend_bool) INI_ORIG_INT(name))
|
||||
|
||||
#define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number TSRMLS_CC)
|
||||
#define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries(module_number TSRMLS_CC)
|
||||
#define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module)
|
||||
|
||||
#define REGISTER_INI_DISPLAYER(name, displayer) zend_ini_register_displayer((name), sizeof(name)-1, displayer)
|
||||
#define REGISTER_INI_DISPLAYER(name, displayer) zend_ini_register_displayer((name), sizeof(name), displayer)
|
||||
#define REGISTER_INI_BOOLEAN(name) REGISTER_INI_DISPLAYER(name, zend_ini_boolean_displayer_cb)
|
||||
|
||||
/* Standard message handlers */
|
||||
|
||||
+55
-49
@@ -29,6 +29,10 @@
|
||||
#include "zend_ini_scanner.h"
|
||||
#include "zend_extensions.h"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#include "win32/syslog.h"
|
||||
#endif
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
#define YYSTYPE zval
|
||||
|
||||
@@ -49,14 +53,13 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
{
|
||||
int i_result;
|
||||
int i_op1, i_op2;
|
||||
int str_len;
|
||||
char str_result[MAX_LENGTH_OF_LONG];
|
||||
|
||||
i_op1 = atoi(Z_STRVAL_P(op1));
|
||||
zend_string_free(Z_STR_P(op1));
|
||||
free(Z_STRVAL_P(op1));
|
||||
if (op2) {
|
||||
i_op2 = atoi(Z_STRVAL_P(op2));
|
||||
zend_string_free(Z_STR_P(op2));
|
||||
free(Z_STRVAL_P(op2));
|
||||
} else {
|
||||
i_op2 = 0;
|
||||
}
|
||||
@@ -82,8 +85,11 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
break;
|
||||
}
|
||||
|
||||
str_len = zend_sprintf(str_result, "%d", i_result);
|
||||
ZVAL_PSTRINGL(result, str_result, str_len);
|
||||
Z_STRLEN_P(result) = zend_sprintf(str_result, "%d", i_result);
|
||||
Z_STRVAL_P(result) = (char *) malloc(Z_STRLEN_P(result)+1);
|
||||
memcpy(Z_STRVAL_P(result), str_result, Z_STRLEN_P(result));
|
||||
Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
|
||||
Z_TYPE_P(result) = IS_STRING;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -91,7 +97,10 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
*/
|
||||
static void zend_ini_init_string(zval *result)
|
||||
{
|
||||
ZVAL_EMPTY_PSTRING(result);
|
||||
Z_STRVAL_P(result) = malloc(1);
|
||||
Z_STRVAL_P(result)[0] = 0;
|
||||
Z_STRLEN_P(result) = 0;
|
||||
Z_TYPE_P(result) = IS_STRING;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -99,12 +108,13 @@ static void zend_ini_init_string(zval *result)
|
||||
*/
|
||||
static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
|
||||
{
|
||||
int op1_len = Z_STRLEN_P(op1);
|
||||
int length = op1_len + Z_STRLEN_P(op2);
|
||||
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
|
||||
|
||||
ZVAL_NEW_STR(result, zend_string_realloc(Z_STR_P(op1), length, 1));
|
||||
memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
|
||||
Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
|
||||
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
|
||||
Z_STRVAL_P(result)[length] = 0;
|
||||
Z_STRLEN_P(result) = length;
|
||||
Z_TYPE_P(result) = IS_STRING;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -112,25 +122,18 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
|
||||
*/
|
||||
static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
|
||||
{
|
||||
zval *c, tmp;
|
||||
zval z_constant;
|
||||
|
||||
/* If name contains ':' it is not a constant. Bug #26893. */
|
||||
if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
|
||||
&& (c = zend_get_constant(Z_STR_P(name) TSRMLS_CC)) != 0) {
|
||||
if (Z_TYPE_P(c) != IS_STRING) {
|
||||
ZVAL_COPY_VALUE(&tmp, c);
|
||||
if (Z_OPT_CONSTANT(tmp)) {
|
||||
zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC);
|
||||
}
|
||||
zval_opt_copy_ctor(&tmp);
|
||||
convert_to_string(&tmp);
|
||||
c = &tmp;
|
||||
}
|
||||
ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c));
|
||||
if (c == &tmp) {
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
zend_string_free(Z_STR_P(name));
|
||||
&& zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
|
||||
/* z_constant is emalloc()'d */
|
||||
convert_to_string(&z_constant);
|
||||
Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant));
|
||||
Z_STRLEN_P(result) = Z_STRLEN(z_constant);
|
||||
Z_TYPE_P(result) = Z_TYPE(z_constant);
|
||||
zval_dtor(&z_constant);
|
||||
free(Z_STRVAL_P(name));
|
||||
} else {
|
||||
*result = *name;
|
||||
}
|
||||
@@ -145,12 +148,14 @@ static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
|
||||
char *envvar;
|
||||
|
||||
/* Fetch configuration option value */
|
||||
if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name), &curval) == SUCCESS) {
|
||||
ZVAL_PSTRINGL(result, Z_STRVAL(curval), Z_STRLEN(curval));
|
||||
if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) {
|
||||
Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval));
|
||||
Z_STRLEN_P(result) = Z_STRLEN(curval);
|
||||
/* ..or if not found, try ENV */
|
||||
} else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
|
||||
(envvar = getenv(Z_STRVAL_P(name))) != NULL) {
|
||||
ZVAL_PSTRING(result, envvar);
|
||||
Z_STRVAL_P(result) = strdup(envvar);
|
||||
Z_STRLEN_P(result) = strlen(envvar);
|
||||
} else {
|
||||
zend_ini_init_string(result);
|
||||
}
|
||||
@@ -159,7 +164,7 @@ static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
|
||||
|
||||
/* {{{ ini_error()
|
||||
*/
|
||||
static void ini_error(const char *msg)
|
||||
static void ini_error(char *msg)
|
||||
{
|
||||
char *error_buf;
|
||||
int error_buf_len;
|
||||
@@ -178,10 +183,9 @@ static void ini_error(const char *msg)
|
||||
|
||||
if (CG(ini_parser_unbuffered_errors)) {
|
||||
#ifdef PHP_WIN32
|
||||
MessageBox(NULL, error_buf, "PHP Error", MB_OK|MB_TOPMOST|0x00200000L);
|
||||
#else
|
||||
fprintf(stderr, "PHP: %s", error_buf);
|
||||
syslog(LOG_ALERT, "PHP: %s (%s)", error_buf, GetCommandLine());
|
||||
#endif
|
||||
fprintf(stderr, "PHP: %s", error_buf);
|
||||
} else {
|
||||
zend_error(E_WARNING, "%s", error_buf);
|
||||
}
|
||||
@@ -264,6 +268,7 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s
|
||||
%token TC_QUOTED_STRING
|
||||
%token BOOL_TRUE
|
||||
%token BOOL_FALSE
|
||||
%token NULL_NULL
|
||||
%token END_OF_LINE
|
||||
%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
|
||||
%left '|' '&' '^'
|
||||
@@ -282,26 +287,26 @@ statement:
|
||||
printf("SECTION: [%s]\n", Z_STRVAL($2));
|
||||
#endif
|
||||
ZEND_INI_PARSER_CB(&$2, NULL, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG TSRMLS_CC);
|
||||
zend_string_release(Z_STR($2));
|
||||
free(Z_STRVAL($2));
|
||||
}
|
||||
| TC_LABEL '=' string_or_value {
|
||||
#if DEBUG_CFG_PARSER
|
||||
printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3));
|
||||
#endif
|
||||
ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
|
||||
zend_string_release(Z_STR($1));
|
||||
zend_string_release(Z_STR($3));
|
||||
free(Z_STRVAL($1));
|
||||
zval_internal_dtor(&$3);
|
||||
}
|
||||
| TC_OFFSET option_offset ']' '=' string_or_value {
|
||||
#if DEBUG_CFG_PARSER
|
||||
printf("OFFSET: '%s'[%s] = '%s'\n", Z_STRVAL($1), Z_STRVAL($2), Z_STRVAL($5));
|
||||
#endif
|
||||
ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
|
||||
zend_string_release(Z_STR($1));
|
||||
zend_string_release(Z_STR($2));
|
||||
zend_string_release(Z_STR($5));
|
||||
free(Z_STRVAL($1));
|
||||
free(Z_STRVAL($2));
|
||||
zval_internal_dtor(&$5);
|
||||
}
|
||||
| TC_LABEL { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); zend_string_release(Z_STR($1)); }
|
||||
| TC_LABEL { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); }
|
||||
| END_OF_LINE
|
||||
;
|
||||
|
||||
@@ -314,6 +319,7 @@ string_or_value:
|
||||
expr { $$ = $1; }
|
||||
| BOOL_TRUE { $$ = $1; }
|
||||
| BOOL_FALSE { $$ = $1; }
|
||||
| NULL_NULL { $$ = $1; }
|
||||
| END_OF_LINE { zend_ini_init_string(&$$); }
|
||||
;
|
||||
|
||||
@@ -323,8 +329,8 @@ option_offset:
|
||||
;
|
||||
|
||||
encapsed_list:
|
||||
encapsed_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
| encapsed_list TC_QUOTED_STRING { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
encapsed_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| encapsed_list TC_QUOTED_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| /* empty */ { zend_ini_init_string(&$$); }
|
||||
;
|
||||
|
||||
@@ -332,18 +338,18 @@ var_string_list_section:
|
||||
cfg_var_ref { $$ = $1; }
|
||||
| constant_literal { $$ = $1; }
|
||||
| '"' encapsed_list '"' { $$ = $2; }
|
||||
| var_string_list_section cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
| var_string_list_section constant_literal { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
| var_string_list_section '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); zend_string_free(Z_STR($3)); }
|
||||
| var_string_list_section cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| var_string_list_section constant_literal { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| var_string_list_section '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
|
||||
;
|
||||
|
||||
var_string_list:
|
||||
cfg_var_ref { $$ = $1; }
|
||||
| constant_string { $$ = $1; }
|
||||
| '"' encapsed_list '"' { $$ = $2; }
|
||||
| var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
| var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
|
||||
| var_string_list '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); zend_string_free(Z_STR($3)); }
|
||||
| var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
|
||||
| var_string_list '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
|
||||
;
|
||||
|
||||
expr:
|
||||
@@ -357,7 +363,7 @@ expr:
|
||||
;
|
||||
|
||||
cfg_var_ref:
|
||||
TC_DOLLAR_CURLY TC_VARNAME '}' { zend_ini_get_var(&$$, &$2 TSRMLS_CC); zend_string_free(Z_STR($2)); }
|
||||
TC_DOLLAR_CURLY TC_VARNAME '}' { zend_ini_get_var(&$$, &$2 TSRMLS_CC); free(Z_STRVAL($2)); }
|
||||
;
|
||||
|
||||
constant_literal:
|
||||
|
||||
+2638
-2471
File diff suppressed because it is too large.
Load diff
@@ -25,6 +25,7 @@
|
||||
/* Scanner modes */
|
||||
#define ZEND_INI_SCANNER_NORMAL 0 /* Normal mode. [DEFAULT] */
|
||||
#define ZEND_INI_SCANNER_RAW 1 /* Raw mode. Option values are not parsed */
|
||||
#define ZEND_INI_SCANNER_TYPED 2 /* Typed mode. */
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
int zend_ini_scanner_get_lineno(TSRMLS_D);
|
||||
|
||||
+64
-10
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include "zend.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_globals.h"
|
||||
#include <zend_ini_parser.h>
|
||||
#include "zend_ini_scanner.h"
|
||||
@@ -131,18 +132,66 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
/* Eat trailing whitespace */
|
||||
#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X')
|
||||
|
||||
#define zend_ini_copy_value(retval, str, len) \
|
||||
ZVAL_NEW_STR(retval, zend_string_init(str, len, 1))
|
||||
#define zend_ini_copy_value(retval, str, len) { \
|
||||
Z_STRVAL_P(retval) = zend_strndup(str, len); \
|
||||
Z_STRLEN_P(retval) = len; \
|
||||
Z_TYPE_P(retval) = IS_STRING; \
|
||||
}
|
||||
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED) { \
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
}
|
||||
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
return type; \
|
||||
static inline int convert_to_number(zval *retval, const char *str, const int str_len)
|
||||
{
|
||||
zend_uchar type;
|
||||
int overflow;
|
||||
long lval;
|
||||
double dval;
|
||||
|
||||
if ((type = is_numeric_string_ex(str, str_len, &lval, &dval, 0, &overflow)) != 0) {
|
||||
if (type == IS_LONG) {
|
||||
ZVAL_LONG(retval, lval);
|
||||
return SUCCESS;
|
||||
} else if (type == IS_DOUBLE && !overflow) {
|
||||
ZVAL_DOUBLE(retval, dval);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
static void zend_ini_copy_typed_value(zval *retval, const int type, const char *str, int len)
|
||||
{
|
||||
switch (type) {
|
||||
case BOOL_FALSE:
|
||||
case BOOL_TRUE:
|
||||
ZVAL_BOOL(retval, type == BOOL_TRUE);
|
||||
break;
|
||||
|
||||
case NULL_NULL:
|
||||
ZVAL_NULL(retval);
|
||||
break;
|
||||
|
||||
case TC_NUMBER:
|
||||
if (convert_to_number(retval, str, len) == SUCCESS) {
|
||||
break;
|
||||
}
|
||||
/* intentional fall-through */
|
||||
default:
|
||||
zend_ini_copy_value(retval, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void _yy_push_state(int new_state TSRMLS_DC)
|
||||
{
|
||||
zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
|
||||
zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
|
||||
YYSETCONDITION(new_state);
|
||||
}
|
||||
|
||||
@@ -150,7 +199,8 @@ static void _yy_push_state(int new_state TSRMLS_DC)
|
||||
|
||||
static void yy_pop_state(TSRMLS_D)
|
||||
{
|
||||
int *stack_state = zend_stack_top(&SCNG(state_stack));
|
||||
int *stack_state;
|
||||
zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
|
||||
YYSETCONDITION(*stack_state);
|
||||
zend_stack_del_top(&SCNG(state_stack));
|
||||
}
|
||||
@@ -169,7 +219,7 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
|
||||
static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
|
||||
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED) {
|
||||
zend_error(E_WARNING, "Invalid scanner mode");
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -184,7 +234,7 @@ static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
|
||||
ini_filename = NULL;
|
||||
}
|
||||
|
||||
zend_stack_init(&SCNG(state_stack), sizeof(int));
|
||||
zend_stack_init(&SCNG(state_stack));
|
||||
BEGIN(INITIAL);
|
||||
|
||||
return SUCCESS;
|
||||
@@ -419,10 +469,14 @@ SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
RETURN_TOKEN(BOOL_TRUE, "1", 1);
|
||||
}
|
||||
|
||||
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
RETURN_TOKEN(BOOL_FALSE, "", 0);
|
||||
}
|
||||
|
||||
<INITIAL,ST_VALUE>("null"){TABS_AND_SPACES}* {
|
||||
RETURN_TOKEN(NULL_NULL, "", 0);
|
||||
}
|
||||
|
||||
<INITIAL>{LABEL} { /* Get option name */
|
||||
/* Eat leading whitespace */
|
||||
EAT_LEADING_WHITESPACE();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* Generated by re2c 0.13.5 */
|
||||
#line 3 "Zend/zend_ini_scanner_defs.h"
|
||||
|
||||
enum YYCONDTYPE {
|
||||
yycINITIAL,
|
||||
yycST_OFFSET,
|
||||
yycST_SECTION_VALUE,
|
||||
yycST_VALUE,
|
||||
yycST_SECTION_RAW,
|
||||
yycST_DOUBLE_QUOTES,
|
||||
yycST_VARNAME,
|
||||
yycST_RAW,
|
||||
};
|
||||
/* Generated by re2c 0.13.5 */
|
||||
#line 3 "Zend/zend_ini_scanner_defs.h"
|
||||
|
||||
enum YYCONDTYPE {
|
||||
yycINITIAL,
|
||||
yycST_OFFSET,
|
||||
yycST_SECTION_VALUE,
|
||||
yycST_VALUE,
|
||||
yycST_SECTION_RAW,
|
||||
yycST_DOUBLE_QUOTES,
|
||||
yycST_VARNAME,
|
||||
yycST_RAW,
|
||||
};
|
||||
+98
-106
@@ -31,27 +31,24 @@ ZEND_API zend_class_entry *zend_ce_serializable;
|
||||
|
||||
/* {{{ zend_call_method
|
||||
Only returns the returned zval if retval_ptr != NULL */
|
||||
ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
|
||||
ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
|
||||
{
|
||||
int result;
|
||||
zend_fcall_info fci;
|
||||
zval retval;
|
||||
zval z_fname;
|
||||
zval *retval;
|
||||
HashTable *function_table;
|
||||
|
||||
zval params[2];
|
||||
zval **params[2];
|
||||
|
||||
if (param_count > 0) {
|
||||
ZVAL_COPY_VALUE(¶ms[0], arg1);
|
||||
}
|
||||
if (param_count > 1) {
|
||||
ZVAL_COPY_VALUE(¶ms[1], arg2);
|
||||
}
|
||||
params[0] = &arg1;
|
||||
params[1] = &arg2;
|
||||
|
||||
fci.size = sizeof(fci);
|
||||
/*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
|
||||
fci.object = (object && Z_TYPE_P(object) == IS_OBJECT) ? Z_OBJ_P(object) : NULL;
|
||||
ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
|
||||
fci.retval = retval_ptr ? retval_ptr : &retval;
|
||||
fci.object_ptr = object_pp ? *object_pp : NULL;
|
||||
fci.function_name = &z_fname;
|
||||
fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
|
||||
fci.param_count = param_count;
|
||||
fci.params = params;
|
||||
fci.no_separation = 1;
|
||||
@@ -60,15 +57,15 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
|
||||
if (!fn_proxy && !obj_ce) {
|
||||
/* no interest in caching and no information already present that is
|
||||
* needed later inside zend_call_function. */
|
||||
fci.function_table = !object ? EG(function_table) : NULL;
|
||||
ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
|
||||
fci.function_table = !object_pp ? EG(function_table) : NULL;
|
||||
result = zend_call_function(&fci, NULL TSRMLS_CC);
|
||||
zval_ptr_dtor(&fci.function_name);
|
||||
} else {
|
||||
zend_fcall_info_cache fcic;
|
||||
|
||||
fcic.initialized = 1;
|
||||
if (!obj_ce) {
|
||||
obj_ce = object ? Z_OBJCE_P(object) : NULL;
|
||||
obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
|
||||
}
|
||||
if (obj_ce) {
|
||||
function_table = &obj_ce->function_table;
|
||||
@@ -76,9 +73,9 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
|
||||
function_table = EG(function_table);
|
||||
}
|
||||
if (!fn_proxy || !*fn_proxy) {
|
||||
if ((fcic.function_handler = zend_hash_find_ptr(function_table, Z_STR(fci.function_name))) == NULL) {
|
||||
if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
|
||||
/* error at c-level */
|
||||
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
|
||||
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
|
||||
}
|
||||
if (fn_proxy) {
|
||||
*fn_proxy = fcic.function_handler;
|
||||
@@ -87,50 +84,46 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
|
||||
fcic.function_handler = *fn_proxy;
|
||||
}
|
||||
fcic.calling_scope = obj_ce;
|
||||
if (object) {
|
||||
fcic.called_scope = Z_OBJCE_P(object);
|
||||
if (object_pp) {
|
||||
fcic.called_scope = Z_OBJCE_PP(object_pp);
|
||||
} else if (obj_ce &&
|
||||
!(EG(current_execute_data) &&
|
||||
EG(current_execute_data)->called_scope &&
|
||||
instanceof_function(EG(current_execute_data)->called_scope, obj_ce TSRMLS_CC))) {
|
||||
!(EG(called_scope) &&
|
||||
instanceof_function(EG(called_scope), obj_ce TSRMLS_CC))) {
|
||||
fcic.called_scope = obj_ce;
|
||||
} else {
|
||||
fcic.called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
|
||||
fcic.called_scope = EG(called_scope);
|
||||
}
|
||||
fcic.object = object ? Z_OBJ_P(object) : NULL;
|
||||
fcic.object_ptr = object_pp ? *object_pp : NULL;
|
||||
result = zend_call_function(&fci, &fcic TSRMLS_CC);
|
||||
zval_ptr_dtor(&fci.function_name);
|
||||
}
|
||||
if (result == FAILURE) {
|
||||
/* error at c-level */
|
||||
if (!obj_ce) {
|
||||
obj_ce = object ? Z_OBJCE_P(object) : NULL;
|
||||
obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
|
||||
}
|
||||
if (!EG(exception)) {
|
||||
zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
|
||||
zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
|
||||
}
|
||||
}
|
||||
/* copy arguments back, they might be changed by references */
|
||||
if (param_count > 0 && Z_ISREF(params[0]) && !Z_ISREF_P(arg1)) {
|
||||
ZVAL_COPY_VALUE(arg1, ¶ms[0]);
|
||||
}
|
||||
if (param_count > 1 && Z_ISREF(params[1]) && !Z_ISREF_P(arg2)) {
|
||||
ZVAL_COPY_VALUE(arg2, ¶ms[1]);
|
||||
}
|
||||
if (!retval_ptr) {
|
||||
zval_ptr_dtor(&retval);
|
||||
if (!retval_ptr_ptr) {
|
||||
if (retval) {
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return retval_ptr;
|
||||
return *retval_ptr_ptr;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* iterator interface, c-level functions used by engine */
|
||||
|
||||
/* {{{ zend_user_it_new_iterator */
|
||||
ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *retval TSRMLS_DC)
|
||||
ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
|
||||
{
|
||||
zend_call_method_with_0_params(object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", retval);
|
||||
zval *retval;
|
||||
|
||||
return zend_call_method_with_0_params(&object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -139,9 +132,9 @@ ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
|
||||
if (!Z_ISUNDEF(iter->value)) {
|
||||
if (iter->value) {
|
||||
zval_ptr_dtor(&iter->value);
|
||||
ZVAL_UNDEF(&iter->value);
|
||||
iter->value = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -150,10 +143,11 @@ ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS
|
||||
static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
|
||||
zend_user_it_invalidate_current(_iter TSRMLS_CC);
|
||||
zval_ptr_dtor(object);
|
||||
zval_ptr_dtor(&object);
|
||||
efree(iter);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -162,13 +156,13 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
|
||||
{
|
||||
if (_iter) {
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval more;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
zval *more;
|
||||
int result;
|
||||
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
|
||||
if (Z_TYPE(more) != IS_UNDEF) {
|
||||
result = i_zend_is_true(&more TSRMLS_CC);
|
||||
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
|
||||
if (more) {
|
||||
result = i_zend_is_true(more);
|
||||
zval_ptr_dtor(&more);
|
||||
return result ? SUCCESS : FAILURE;
|
||||
}
|
||||
@@ -178,15 +172,15 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_user_it_get_current_data */
|
||||
ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter TSRMLS_DC)
|
||||
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
|
||||
if (Z_ISUNDEF(iter->value)) {
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
|
||||
}
|
||||
return &iter->value;
|
||||
if (!iter->value) {
|
||||
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
|
||||
}
|
||||
*data = &iter->value;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -204,31 +198,30 @@ static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, cha
|
||||
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval retval;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
zval *retval;
|
||||
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
|
||||
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
|
||||
|
||||
if (Z_TYPE(retval) != IS_UNDEF) {
|
||||
ZVAL_ZVAL(key, &retval, 1, 1);
|
||||
if (retval) {
|
||||
ZVAL_ZVAL(key, retval, 1, 1);
|
||||
} else {
|
||||
if (!EG(exception)) {
|
||||
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name->val);
|
||||
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
|
||||
}
|
||||
|
||||
ZVAL_LONG(key, 0);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_user_it_move_forward */
|
||||
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
|
||||
zend_user_it_invalidate_current(_iter TSRMLS_CC);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
|
||||
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -236,10 +229,10 @@ ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
|
||||
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval *object = (zval*)iter->it.data;
|
||||
|
||||
zend_user_it_invalidate_current(_iter TSRMLS_CC);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
|
||||
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -264,12 +257,11 @@ static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zva
|
||||
|
||||
iterator = emalloc(sizeof(zend_user_iterator));
|
||||
|
||||
zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC);
|
||||
|
||||
ZVAL_COPY(&iterator->it.data, object);
|
||||
Z_ADDREF_P(object);
|
||||
iterator->it.data = (void*)object;
|
||||
iterator->it.funcs = ce->iterator_funcs.funcs;
|
||||
iterator->ce = Z_OBJCE_P(object);
|
||||
ZVAL_UNDEF(&iterator->value);
|
||||
iterator->value = NULL;
|
||||
return (zend_object_iterator*)iterator;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -277,23 +269,22 @@ static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zva
|
||||
/* {{{ zend_user_it_get_new_iterator */
|
||||
ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
|
||||
{
|
||||
zval iterator;
|
||||
zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC);
|
||||
zend_object_iterator *new_iterator;
|
||||
zend_class_entry *ce_it;
|
||||
|
||||
zend_user_it_new_iterator(ce, object, &iterator TSRMLS_CC);
|
||||
ce_it = (Z_TYPE(iterator) == IS_OBJECT &&
|
||||
Z_OBJ_HT(iterator)->get_class_entry) ? Z_OBJCE(iterator) : NULL;
|
||||
zend_class_entry *ce_it = iterator && Z_TYPE_P(iterator) == IS_OBJECT ? Z_OBJCE_P(iterator) : NULL;
|
||||
|
||||
if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && Z_OBJ(iterator) == Z_OBJ_P(object))) {
|
||||
if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
|
||||
if (!EG(exception)) {
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name->val : Z_OBJCE_P(object)->name->val);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name : Z_OBJCE_P(object)->name);
|
||||
}
|
||||
if (iterator) {
|
||||
zval_ptr_dtor(&iterator);
|
||||
}
|
||||
zval_ptr_dtor(&iterator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_iterator = ce_it->get_iterator(ce_it, &iterator, by_ref TSRMLS_CC);
|
||||
new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
|
||||
zval_ptr_dtor(&iterator);
|
||||
return new_iterator;
|
||||
}
|
||||
@@ -303,7 +294,7 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
|
||||
static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
/* check that class_type is traversable at c-level or implements at least one of 'aggregate' and 'Iterator' */
|
||||
uint32_t i;
|
||||
zend_uint i;
|
||||
|
||||
if (class_type->get_iterator || (class_type->parent && class_type->parent->get_iterator)) {
|
||||
return SUCCESS;
|
||||
@@ -314,10 +305,10 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
|
||||
}
|
||||
}
|
||||
zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
|
||||
class_type->name->val,
|
||||
zend_ce_traversable->name->val,
|
||||
zend_ce_iterator->name->val,
|
||||
zend_ce_aggregate->name->val);
|
||||
class_type->name,
|
||||
zend_ce_traversable->name,
|
||||
zend_ce_iterator->name,
|
||||
zend_ce_aggregate->name);
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -337,9 +328,9 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||
for (i = 0; i < class_type->num_interfaces; i++) {
|
||||
if (class_type->interfaces[i] == zend_ce_iterator) {
|
||||
zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
|
||||
class_type->name->val,
|
||||
interface->name->val,
|
||||
zend_ce_iterator->name->val);
|
||||
class_type->name,
|
||||
interface->name,
|
||||
zend_ce_iterator->name);
|
||||
return FAILURE;
|
||||
}
|
||||
if (class_type->interfaces[i] == zend_ce_traversable) {
|
||||
@@ -369,9 +360,9 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
|
||||
/* c-level get_iterator cannot be changed */
|
||||
if (class_type->get_iterator == zend_user_it_get_new_iterator) {
|
||||
zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
|
||||
class_type->name->val,
|
||||
interface->name->val,
|
||||
zend_ce_aggregate->name->val);
|
||||
class_type->name,
|
||||
interface->name,
|
||||
zend_ce_aggregate->name);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -406,26 +397,26 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
|
||||
/* }}}*/
|
||||
|
||||
/* {{{ zend_user_serialize */
|
||||
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC)
|
||||
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry * ce = Z_OBJCE_P(object);
|
||||
zval retval;
|
||||
zval *retval;
|
||||
int result;
|
||||
|
||||
zend_call_method_with_0_params(object, ce, &ce->serialize_func, "serialize", &retval);
|
||||
zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
|
||||
|
||||
|
||||
if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
|
||||
if (!retval || EG(exception)) {
|
||||
result = FAILURE;
|
||||
} else {
|
||||
switch(Z_TYPE(retval)) {
|
||||
switch(Z_TYPE_P(retval)) {
|
||||
case IS_NULL:
|
||||
/* we could also make this '*buf_len = 0' but this allows to skip variables */
|
||||
zval_ptr_dtor(&retval);
|
||||
return FAILURE;
|
||||
case IS_STRING:
|
||||
*buffer = (unsigned char*)estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
|
||||
*buf_len = Z_STRLEN(retval);
|
||||
*buffer = (unsigned char*)estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
||||
*buf_len = Z_STRLEN_P(retval);
|
||||
result = SUCCESS;
|
||||
break;
|
||||
default: /* failure */
|
||||
@@ -436,22 +427,23 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, uint32_t
|
||||
}
|
||||
|
||||
if (result == FAILURE && !EG(exception)) {
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name->val);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_user_unserialize */
|
||||
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC)
|
||||
ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
|
||||
{
|
||||
zval zdata;
|
||||
zval * zdata;
|
||||
|
||||
object_init_ex(object, ce);
|
||||
object_init_ex(*object, ce);
|
||||
|
||||
ZVAL_STRINGL(&zdata, (char*)buf, buf_len);
|
||||
MAKE_STD_ZVAL(zdata);
|
||||
ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
|
||||
|
||||
zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, &zdata);
|
||||
zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
|
||||
|
||||
zval_ptr_dtor(&zdata);
|
||||
|
||||
@@ -463,17 +455,17 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_class_entry *ce = Z_OBJCE_P(object);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name->val);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name);
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_class_unserialize_deny(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name->val);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name);
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
Loaded 100 of 1556 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user