Compare commits
1482 Commits
Author | SHA1 | Date |
---|---|---|
lijunlong | 9c9495b6f9 | |
lijunlong | 7b7fcbe078 | |
swananan | 478d980900 | |
Yichun Zhang (agentzh) | ad33f56e91 | |
Johnny Wang | 8978f0426f | |
ruoyidero | a71e039a0d | |
Johnny Wang | 8760b0af4a | |
lijunlong | 6fe9e3f7e6 | |
lijunlong | aecf396061 | |
lijunlong | 348fcffc2b | |
lijunlong | 5196b0d9ac | |
Johnny Wang | 2f97ded92b | |
swananan | d086dbcfc5 | |
swananan | 6278b1aeae | |
Johnny Wang | cf8c2f827e | |
lijunlong | cd976f9286 | |
Yichun Zhang (agentzh) | dfbc003724 | |
Johnny Wang | a1730aba13 | |
Yichun Zhang (agentzh) | 055e86bff2 | |
Johnny Wang | f8e47102b7 | |
Yichun Zhang (agentzh) | 0d32bd9bdb | |
Johnny Wang | 9fcf59d7b2 | |
Johnny Wang | 3c838ca999 | |
Johnny Wang | 222b48ab61 | |
Yichun Zhang (agentzh) | 3e4114a5f6 | |
Johnny Wang | 7a923b387d | |
Johnny Wang | d5c5ccbad2 | |
Johnny Wang | 21eb0377ac | |
jiahao | 4e6a67922c | |
jiahao | 6b8e60f250 | |
jiahao | 9c7427f75f | |
jiahao | 95f7d3297f | |
jiahao | b14716be04 | |
jiahao | acfb47448b | |
jiahao | 0eae2a784b | |
jiahao | 05362687c2 | |
jiahao | 965ccfb230 | |
jiahao | 56acc7b9c2 | |
jiahao | f5eaffb12a | |
jiahao | 86267fc022 | |
jiahao | 90363486a5 | |
jiahao | eaa41a295a | |
jiahao | adae554762 | |
jiahao | 691cddfe90 | |
jiahao | 3b626720b2 | |
jiahao | 42e8796c67 | |
jiahao | 7043c6b9b7 | |
jiahao | 3aec27a4e8 | |
jiahao | d1846b1c9d | |
jiahao | 369f93ccbd | |
Josh Soref | e7e21f9b40 | |
lijunlong | 21c58ae1f5 | |
fesily | 0d3f8f0a0b | |
fesily | d0a77980eb | |
罗泽轩 | 47eb6f3962 | |
Johnny Wang | 546175e3c5 | |
lijunlong | ae42a6bd86 | |
Johnny Wang | 37fe0d4314 | |
Johnny Wang | e699097b04 | |
lijunlong | 74d747d9b4 | |
Johnny Wang | 733ab1d043 | |
Johnny Wang | 4082fb0d1d | |
Johnny Wang | fb254e1ff6 | |
jiahao | 202d218840 | |
jiahao | 1b145ac3ca | |
jiahao | 5c9d9661c7 | |
Artiom Vaskov | 231eebec0b | |
lijunlong | fa95e176fb | |
Yichun Zhang (agentzh) | f6b6f10fc0 | |
Johnny Wang | e44c540725 | |
Johnny Wang | d84bf6756d | |
Johnny Wang | a7142a8934 | |
Johnny Wang | f3a85d860f | |
RocFang | 0c2d10af40 | |
Johnny Wang | 7e1cf985cf | |
Johnny Wang | 4a092bb740 | |
jiahao | 6568f3f2f1 | |
jiahao | 9781850623 | |
lijunlong | 7df6239881 | |
jiahao | 72ca953bf2 | |
Johnny Wang | 5c7ad29352 | |
Johnny Wang | c2bf0b421c | |
Zhefeng Chen | 9fa420424a | |
Krishna Harsha Voora | c7a3cfe57f | |
Johnny Wang | ab5a632278 | |
Johnny Wang | 1befa30baa | |
Yichun Zhang (agentzh) | df4d005211 | |
Yichun Zhang (agentzh) | 04ef2ec590 | |
John Bampton | f39a584775 | |
wangyao | c93ef77262 | |
Yao Wang | 174f72b95c | |
jiahao | ee23eb4a51 | |
jiahao | 6aeb03501f | |
jiahao | 805df3d657 | |
jiahao | 077b4dcef8 | |
jiahao | 4933c6f612 | |
jiahao | ca141a4b66 | |
jiahao | 13700cacb6 | |
jiahao | 9d1eb80e1e | |
jiahao | 826e7286e0 | |
jiahao | 4b99fd3c0e | |
jiahao | 66a8c85811 | |
Johnny Wang | 46610182dd | |
Johnny Wang | 4b5ec7edd7 | |
jiahao | 42410a71cd | |
Johnny Wang | fcac763f22 | |
jiahao | b3c6965092 | |
jiahao | e51b659141 | |
jiahao | e06dd8ff32 | |
jiahao | c5c858bbca | |
jiahao | 34645f7dc8 | |
jiahao | 7586293fe7 | |
jiahao | 99d01cdc1c | |
jiahao | bd1b387c3d | |
jiahao | 12db974fc0 | |
jiahao | 7d262c5c8d | |
jiahao | b9a6f107e2 | |
jiahao | 2be7ad590e | |
Johnny Wang | 6cd17e53fa | |
John Bampton | e0eb531243 | |
Zhang Xiang | 40104504e5 | |
Johnny Wang | b4592301ad | |
Johnny Wang | 1562e11be5 | |
Johnny Wang | 3abb2c7fae | |
Yichun Zhang (agentzh) | de3e659ef5 | |
jiahao | 1c4063664e | |
jiahao | 72d8adc75c | |
jiahao | d5f130fbff | |
jiahao | 934a3102dc | |
Johnny Wang | b9bc185f79 | |
Johnny Wang | f43cd23f83 | |
Johnny Wang | 0e1cad8190 | |
Johnny Wang | ce740cba10 | |
Johnny Wang | 8fa9533c5e | |
Yichun Zhang (agentzh) | 29b901d4cd | |
Yichun Zhang (agentzh) | fcee0d36da | |
Yichun Zhang (agentzh) | bae27d3eff | |
Yichun Zhang (agentzh) | 931adca76a | |
Yichun Zhang (agentzh) | 62c3cb72a1 | |
jiahao | 8a4605a933 | |
jiahao | a8696337a6 | |
Johnny Wang | 771e9e678e | |
Johnny Wang | f9634628c1 | |
Yichun Zhang (agentzh) | 2d5e6626ba | |
Yichun Zhang (agentzh) | 917e5ec2ac | |
Johnny Wang | 083f003647 | |
Johnny Wang | 3d99a48000 | |
Johnny Wang | 3f4dc6dd9e | |
Johnny | 9db4ad6a87 | |
Johnny | 2e3312a46e | |
罗泽轩 | 20d2bd74bf | |
Yichun Zhang (agentzh) | d60de6c3c5 | |
Yichun Zhang (agentzh) | 5301a3193f | |
Yichun Zhang (agentzh) | 0b73295f36 | |
Yichun Zhang (agentzh) | 4eab59c2f4 | |
Yichun Zhang (agentzh) | 97a49f7644 | |
Yichun Zhang (agentzh) | b73e42d86a | |
Yichun Zhang (agentzh) | 54f2309e2b | |
Yichun Zhang (agentzh) | 865a672104 | |
Yichun Zhang (agentzh) | fbe8117d57 | |
Yichun Zhang (agentzh) | eb1ea4aac3 | |
Yichun Zhang (agentzh) | 275739cf1f | |
Yichun Zhang (agentzh) | 5d118a38a6 | |
Yichun Zhang (agentzh) | a2996edf22 | |
Yichun Zhang (agentzh) | 1dfcf81667 | |
Yichun Zhang (agentzh) | b236f833b4 | |
Yichun Zhang (agentzh) | b78c057b6f | |
lijunlong | 4a006e09b4 | |
Yichun Zhang (agentzh) | 51b70c82b8 | |
Yichun Zhang (agentzh) | f12147f5f4 | |
Yichun Zhang (agentzh) | d017d4cf24 | |
罗泽轩 | 2894a41f02 | |
Yichun Zhang (agentzh) | 3fd2b53ccb | |
Yichun Zhang (agentzh) | 156fd1fcf9 | |
Yichun Zhang (agentzh) | 13b879394a | |
Yichun Zhang (agentzh) | 90894b2b48 | |
Yichun Zhang (agentzh) | 1aa7a2bcd3 | |
Yichun Zhang (agentzh) | f85fe22ac2 | |
Meathill | 11fbbe5c62 | |
Yichun Zhang (agentzh) | cee71edf71 | |
root | 50717794af | |
lijunlong | 6985198d46 | |
Yichun Zhang (agentzh) | 4568281eaf | |
Yichun Zhang (agentzh) | afa9800e79 | |
Thibault Charbonnier | 5a03142ec3 | |
Thibault Charbonnier | e3615c3522 | |
Thibault Charbonnier | 947365b3b1 | |
lijunlong | 61f6ecb419 | |
Thibault Charbonnier | fc17ac5bc2 | |
Thibault Charbonnier | 463d3e1de9 | |
Thibault Charbonnier | e48becb75d | |
Thibault Charbonnier | 549d68b71b | |
spacewander | 4debfd5a3c | |
Thibault Charbonnier | 4b5cb7a546 | |
Yichun Zhang (agentzh) | 7ed8526af7 | |
Yichun Zhang (agentzh) | 563ecc30f7 | |
Yichun Zhang (agentzh) | 7dfeed5921 | |
Yichun Zhang (agentzh) | 05db2b8e84 | |
Yichun Zhang (agentzh) | 4ee261201d | |
Yichun Zhang (agentzh) | 6b71480115 | |
Yichun Zhang (agentzh) | 8cf88e3b13 | |
Yichun Zhang (agentzh) | 2ac0ad9f03 | |
Thibault Charbonnier | 721d7dacc4 | |
Thibault Charbonnier | 9e1d025f80 | |
Thibault Charbonnier | e40f1ccb4a | |
Namrata Bhave | 56bfefd625 | |
Yichun Zhang (agentzh) | a89a0a54b8 | |
Thibault Charbonnier | 23f96dc81e | |
Thibault Charbonnier | 2991c49b69 | |
Thibault Charbonnier | c1a0a9ad8f | |
Thibault Charbonnier | d856e2bf4b | |
Thibault Charbonnier | 82cd12a2ae | |
Thibault Charbonnier | 28f76c1d27 | |
Thibault Charbonnier | 268229af83 | |
Thibault Charbonnier | 6d7249f1c4 | |
Thibault Charbonnier | d6ff771c82 | |
Yichun Zhang (agentzh) | 41abd0f3b5 | |
Yichun Zhang (agentzh) | 29af6de924 | |
Yichun Zhang (agentzh) | f17fe6edc1 | |
Yichun Zhang (agentzh) | 3a630bb020 | |
Yichun Zhang (agentzh) | d4d86a8b0c | |
Thibault Charbonnier | 7508c18522 | |
Thibault Charbonnier | df6c3bcdcb | |
Thibault Charbonnier | 9b1dbb6027 | |
Thibault Charbonnier | 01f212ce9f | |
Thibault Charbonnier | a5248e03d5 | |
Thibault Charbonnier | 9ce78f62c5 | |
Thibault Charbonnier | 21dfc48bb5 | |
Thibault Charbonnier | bad7098d88 | |
Thibault Charbonnier | cc79822109 | |
Thibault Charbonnier | 4995101388 | |
Yichun Zhang (agentzh) | 3fd0e186bf | |
Yichun Zhang (agentzh) | 19ca6c4e2d | |
Yichun Zhang (agentzh) | 395bed2b14 | |
Yichun Zhang (agentzh) | a717ebd523 | |
Yichun Zhang (agentzh) | 3b1b2374c0 | |
Yichun Zhang (agentzh) | f5d359f8f0 | |
James Le Cuirot | 45a454beec | |
Thibault Charbonnier | 59e4ef5c23 | |
Thibault Charbonnier | 80ba3892c6 | |
Datong Sun | d5f48a8b75 | |
spacewander | cf7516fcbc | |
Thibault Charbonnier | 46237a9c22 | |
spacewander | 34918a30c3 | |
spacewander | 2e480157a3 | |
Thibault Charbonnier | a51fa56086 | |
Thibault Charbonnier | cef09e553f | |
Thibault Charbonnier | 08e9e50782 | |
Thibault Charbonnier | b04577cd47 | |
Thibault Charbonnier | 836c8792d2 | |
Yichun Zhang (agentzh) | 3b6d9a5318 | |
Yichun Zhang (agentzh) | e6188369cd | |
Yichun Zhang (agentzh) | fdf142aabe | |
spacewander | 9e834398de | |
Thibault Charbonnier | 547fdd5fb2 | |
Thibault Charbonnier | 1f3cf84a8a | |
Yichun Zhang (agentzh) | bbef48d25b | |
Yichun Zhang (agentzh) | 45997fc5fe | |
Yichun Zhang (agentzh) | cc9787a290 | |
Yichun Zhang (agentzh) | 2b40d7b8ee | |
Yichun Zhang (agentzh) | bf2e5697e1 | |
Yichun Zhang (agentzh) | 540567e42c | |
Thibault Charbonnier | a32ca0dbbe | |
Thibault Charbonnier | 62d31e53de | |
Thibault Charbonnier | 023b9d4f88 | |
Thibault Charbonnier | 8954793847 | |
Thibault Charbonnier | 0b5ebedd47 | |
Thibault Charbonnier | 7e897a8b2b | |
Yichun Zhang (agentzh) | 99d72856a7 | |
Yichun Zhang (agentzh) | ed32897702 | |
Yichun Zhang (agentzh) | 083403fb43 | |
Yichun Zhang (agentzh) | eff3e0d7db | |
Thibault Charbonnier | 88e214aad2 | |
Thibault Charbonnier | ec8f1b0753 | |
Thibault Charbonnier | 191ca1fdec | |
Yichun Zhang (agentzh) | e2ca65128f | |
Yichun Zhang (agentzh) | 76cd3954e3 | |
Thibault Charbonnier | f238a7542a | |
Thibault Charbonnier | 95cfc25189 | |
Yichun Zhang (agentzh) | 0b956ca748 | |
Thibault Charbonnier | 7630d23428 | |
Thibault Charbonnier | 60589ee251 | |
Thibault Charbonnier | 94d0e8ed52 | |
Yichun Zhang (agentzh) | 892a001f4a | |
Yichun Zhang (agentzh) | 4cb86c999c | |
Thibault Charbonnier | b84a47de27 | |
Thibault Charbonnier | 73c881bddf | |
Thibault Charbonnier | 72962e0125 | |
Thibault Charbonnier | 2e7e51e649 | |
Thibault Charbonnier | 06468602b9 | |
Thibault Charbonnier | 7639fe0dba | |
Thibault Charbonnier | 00a89c4b2d | |
Yichun Zhang (agentzh) | 0964e437bd | |
Yichun Zhang (agentzh) | 4dc7d668cc | |
Thibault Charbonnier | c3b7c3b1b9 | |
Thibault Charbonnier | 3f42731e50 | |
spacewander | 2879e59e7b | |
Thibault Charbonnier | 3c053fff33 | |
Thibault Charbonnier | 7b290a582f | |
Thibault Charbonnier | b5d0128311 | |
Yichun Zhang (agentzh) | f56ee1ecd8 | |
Yichun Zhang (agentzh) | 8c8d51663e | |
Yichun Zhang (agentzh) | 97e580a851 | |
Thibault Charbonnier | 1c11dfa811 | |
Yichun Zhang (agentzh) | e70dfd0fac | |
Yichun Zhang (agentzh) | 8cf0d9b097 | |
Yichun Zhang (agentzh) | e2cb54c1ba | |
Yichun Zhang (agentzh) | 2cfd8e5f04 | |
Yichun Zhang (agentzh) | c441759ce3 | |
Yichun Zhang (agentzh) | 03f09b5c25 | |
Yichun Zhang (agentzh) | b91001a87e | |
Yichun Zhang (agentzh) | 2d5699cfe5 | |
Yichun Zhang (agentzh) | 71b9f46595 | |
Datong Sun | 4500744d5c | |
Yichun Zhang (agentzh) | 4bfd198f28 | |
Yichun Zhang (agentzh) | 37a41b416c | |
Yichun Zhang (agentzh) | e8da00c337 | |
Yichun Zhang (agentzh) | 7453fd5aa0 | |
Yichun Zhang (agentzh) | 15cc7b2683 | |
Yichun Zhang (agentzh) | 5d48d9fea2 | |
Yichun Zhang (agentzh) | f58e6eb013 | |
Yichun Zhang (agentzh) | 6ee19af247 | |
Yichun Zhang (agentzh) | 716f518749 | |
Yichun Zhang (agentzh) | b7244e79a3 | |
Yichun Zhang (agentzh) | 94955589ef | |
Yichun Zhang (agentzh) | 8ac69e032c | |
Yichun Zhang (agentzh) | a0467ffb9b | |
Yichun Zhang (agentzh) | d96b792a9a | |
Yichun Zhang (agentzh) | f868ada155 | |
Yichun Zhang (agentzh) | d09ce06877 | |
Yichun Zhang (agentzh) | 37ed98afaf | |
Yichun Zhang (agentzh) | a245ff1644 | |
Yuansheng | 17384566bb | |
Yichun Zhang (agentzh) | a5e7a17cdf | |
Yichun Zhang (agentzh) | 950bd4ec4d | |
Datong Sun | 34db6fd04c | |
Datong Sun | 0263f89bff | |
Yichun Zhang (agentzh) | fe8f773b1d | |
Yichun Zhang (agentzh) | e5dd25dce6 | |
Yichun Zhang (agentzh) | 18063e9a8c | |
Yichun Zhang (agentzh) | 116b8fe20d | |
Yichun Zhang (agentzh) | 4f0980829a | |
Yichun Zhang (agentzh) | eccf26672c | |
Yichun Zhang (agentzh) | a03c89076c | |
Yichun Zhang (agentzh) | 30cc6a2201 | |
Yichun Zhang (agentzh) | 8a18db029a | |
Yichun Zhang (agentzh) | 25faa6d002 | |
Yichun Zhang (agentzh) | c41a76e485 | |
Yichun Zhang (agentzh) | f3406b5ab3 | |
Yichun Zhang (agentzh) | 51c4a3848d | |
Datong Sun | f0e621b0c4 | |
Yichun Zhang (agentzh) | d6c07852e6 | |
Yichun Zhang (agentzh) | 8b98c7df0f | |
Yichun Zhang (agentzh) | 57166863d3 | |
Yichun Zhang (agentzh) | 15aec7f8f9 | |
Yichun Zhang (agentzh) | 17d6683267 | |
Yichun Zhang (agentzh) | 4e202252f4 | |
Yichun Zhang (agentzh) | 5d0235ea71 | |
Yichun Zhang (agentzh) | 7bf9833472 | |
Yichun Zhang (agentzh) | 27d90f13cf | |
Yichun Zhang (agentzh) | 2f74b9703a | |
Yichun Zhang (agentzh) | abad894952 | |
Yichun Zhang (agentzh) | 506b0b8926 | |
Yichun Zhang (agentzh) | c89133ec7e | |
Yichun Zhang (agentzh) | 372befff8d | |
Yichun Zhang (agentzh) | ea1630562c | |
Yichun Zhang (agentzh) | 7f78188bcb | |
Yichun Zhang (agentzh) | 38b45d7a59 | |
Yichun Zhang (agentzh) | be40a6f25c | |
Yichun Zhang (agentzh) | 3b7ec8ed33 | |
Yichun Zhang (agentzh) | 35588fa607 | |
Yichun Zhang (agentzh) | 994a743f9e | |
Yichun Zhang (agentzh) | a737e8a839 | |
Yichun Zhang (agentzh) | 412ac81f38 | |
Datong Sun | ff89bf3ea1 | |
Yichun Zhang (agentzh) | 395e039e8e | |
spacewander | a4f399b3ac | |
Datong Sun | 8d3ce00348 | |
Yichun Zhang (agentzh) | 4a85469797 | |
Yichun Zhang (agentzh) | 46a1c7adb3 | |
Yichun Zhang (agentzh) | f1ad126b75 | |
Yichun Zhang (agentzh) | 7732e38e4c | |
Datong Sun | 3d8b33f0e8 | |
Yichun Zhang (agentzh) | d11dee9ca8 | |
Yichun Zhang (agentzh) | 7a8fb4bc81 | |
Yichun Zhang (agentzh) | d9d28a5f8b | |
catatsuy | 031778f770 | |
Yichun Zhang (agentzh) | 1555734368 | |
Yichun Zhang (agentzh) | e5b5344238 | |
Francesco Giacomini | 0271201881 | |
Yichun Zhang (agentzh) | 94db027c12 | |
Yichun Zhang (agentzh) | e5767d96e9 | |
Yichun Zhang (agentzh) | 36171ae02b | |
Yichun Zhang (agentzh) | 2267596f54 | |
Yichun Zhang (agentzh) | 2f826961dd | |
Yichun Zhang (agentzh) | 028f5e5dec | |
Yichun Zhang (agentzh) | 2ed7e33a5b | |
Yichun Zhang (agentzh) | fd0bf98d6f | |
Datong Sun | 93f785eed6 | |
Datong Sun | 30fa60ad5d | |
spacewander | ee6b26e347 | |
spacewander | e777a35db3 | |
spacewander | a0dc14761a | |
Yichun Zhang (agentzh) | 93e9da93ec | |
Yichun Zhang (agentzh) | 84734aa1f9 | |
Yichun Zhang (agentzh) | f721f66b4e | |
spacewander | 2cc5ba6c91 | |
Yichun Zhang (agentzh) | dd46539557 | |
Yichun Zhang (agentzh) | 346bba3dc6 | |
Yichun Zhang (agentzh) | 578c4e8ae4 | |
Yichun Zhang (agentzh) | 029f20fd6d | |
Yichun Zhang (agentzh) | 3cf34101c0 | |
Yichun Zhang (agentzh) | d5c201c051 | |
Yichun Zhang (agentzh) | 2db0dd9374 | |
Datong Sun | dbf53c5ced | |
Yichun Zhang (agentzh) | d2618c3135 | |
Yichun Zhang (agentzh) | 317dcbfa8a | |
Yichun Zhang (agentzh) | 2094e6321b | |
Yichun Zhang (agentzh) | a1444be0bf | |
Yichun Zhang (agentzh) | cc81cb09fe | |
Yichun Zhang (agentzh) | d13eb1432f | |
Yichun Zhang (agentzh) | c4a794335b | |
Yichun Zhang (agentzh) | 67e6fb305f | |
Yichun Zhang (agentzh) | 82c70515b3 | |
Yichun Zhang (agentzh) | 0e4016c26d | |
Yichun Zhang (agentzh) | fc75550a08 | |
Yichun Zhang (agentzh) | b3bee63c7d | |
Yichun Zhang (agentzh) | 2656416500 | |
Yichun Zhang (agentzh) | 2097b7fbca | |
Yichun Zhang (agentzh) | 6f624f0003 | |
Yichun Zhang (agentzh) | 58f41155d7 | |
Yichun Zhang (agentzh) | 24fb031d22 | |
Yichun Zhang (agentzh) | 3763c5380e | |
Yichun Zhang (agentzh) | f46beb607b | |
Yichun Zhang (agentzh) | a1109b8dd2 | |
John Wu | fee5626f8c | |
Yichun Zhang (agentzh) | 77ea939d00 | |
Yichun Zhang (agentzh) | 131e15ef47 | |
Yichun Zhang (agentzh) | 8c244301ea | |
Datong Sun | 94766f7a41 | |
Yichun Zhang (agentzh) | 4eae6e2415 | |
Yichun Zhang (agentzh) | 53a86b6abd | |
Yichun Zhang (agentzh) | 3e2540f6a0 | |
Datong Sun | 4b594fdce6 | |
Yichun Zhang (agentzh) | 1f2121b546 | |
Yichun Zhang (agentzh) | 6237430ef4 | |
Yichun Zhang (agentzh) | 967d1261cd | |
Yichun Zhang (agentzh) | 1426d3283d | |
Yichun Zhang (agentzh) | 45a8fb27e4 | |
Yichun Zhang (agentzh) | 3c114dbe46 | |
Yichun Zhang (agentzh) | 20e70449f8 | |
Yichun Zhang (agentzh) | 6614441908 | |
Yichun Zhang (agentzh) | 90fc91567f | |
Yichun Zhang (agentzh) | a0f6653c6a | |
Yichun Zhang (agentzh) | 61586a75e3 | |
Yichun Zhang (agentzh) | 9d36d4f069 | |
Yichun Zhang (agentzh) | b1a85d924b | |
Yichun Zhang (agentzh) | 6994c5e125 | |
Yichun Zhang (agentzh) | 2f20dac034 | |
Yichun Zhang (agentzh) | 098889b2ed | |
Yichun Zhang (agentzh) | 7a9c09de5d | |
Yichun Zhang (agentzh) | 22d66022a6 | |
Yichun Zhang (agentzh) | e2c0799394 | |
Yichun Zhang (agentzh) | 44540173ea | |
Yichun Zhang (agentzh) | 843c260daf | |
Yichun Zhang (agentzh) | a864af25cf | |
Yichun Zhang (agentzh) | a21f5e4631 | |
Yichun Zhang (agentzh) | b0b9544aa5 | |
Yichun Zhang (agentzh) | 3e69abf93c | |
Yichun Zhang (agentzh) | c408e5f68f | |
spacewander | 2223edb87d | |
spacewander | adcff66454 | |
Yichun Zhang (agentzh) | 68fdc6754b | |
Yichun Zhang (agentzh) | 645530f76e | |
Yichun Zhang (agentzh) | 24a6779879 | |
Yichun Zhang (agentzh) | 9fcae3552f | |
Yichun Zhang (agentzh) | 47907fa3a9 | |
Yichun Zhang (agentzh) | f9a2702f5a | |
Yichun Zhang (agentzh) | 58f39e963f | |
Yichun Zhang (agentzh) | 19c6e1fb5c | |
Yichun Zhang (agentzh) | 11284ae527 | |
Yichun Zhang (agentzh) | cf01381428 | |
Yichun Zhang (agentzh) | 7447076d56 | |
Yichun Zhang (agentzh) | 4f54490595 | |
Yichun Zhang (agentzh) | 3b500d7c96 | |
Datong Sun | 3b74625ad3 | |
Yichun Zhang (agentzh) | b1400169a7 | |
Yichun Zhang (agentzh) | bc2068420c | |
Yichun Zhang (agentzh) | b81a5cea66 | |
Yichun Zhang (agentzh) | add30287e1 | |
Yichun Zhang (agentzh) | ce30f58339 | |
Datong Sun | 6e74463f66 | |
Yichun Zhang (agentzh) | 79520a30f8 | |
Yichun Zhang (agentzh) | 5426551809 | |
Yichun Zhang (agentzh) | bcb9b3b698 | |
Yichun Zhang (agentzh) | 9afb06f5eb | |
Yichun Zhang (agentzh) | d94772353a | |
Yichun Zhang (agentzh) | d7da4d6037 | |
Datong Sun | 4950ec7f62 | |
Yichun Zhang (agentzh) | 706dee9b7f | |
Yichun Zhang (agentzh) | 5373add959 | |
Yichun Zhang (agentzh) | a5baad4b83 | |
Yichun Zhang (agentzh) | 0ed12d446c | |
Yichun Zhang (agentzh) | ec8acae28e | |
Yichun Zhang (agentzh) | 0ca75dbf45 | |
Yichun Zhang (agentzh) | e6152d3af4 | |
Yichun Zhang (agentzh) | 1780a1dd5f | |
Yichun Zhang (agentzh) | 509afa3d53 | |
Yichun Zhang (agentzh) | 274808af32 | |
Yichun Zhang (agentzh) | 6e8b2f4984 | |
Yichun Zhang (agentzh) | 6b905f9eef | |
Yichun Zhang (agentzh) | 12b67e3a5c | |
Yichun Zhang (agentzh) | 7d5dd68ded | |
Yuansheng | 7a7576319e | |
Yichun Zhang (agentzh) | e767256038 | |
Yichun Zhang (agentzh) | a8ea810fdc | |
Yichun Zhang (agentzh) | dafd10b27d | |
Jukka Raimovaara | eb8fc7771d | |
Yuansheng | 79dc3c56aa | |
Yichun Zhang (agentzh) | 391709ce4d | |
Yichun Zhang (agentzh) | 78af48d106 | |
Yichun Zhang (agentzh) | 34c5e749b7 | |
Yichun Zhang (agentzh) | 5deaa06788 | |
Yichun Zhang (agentzh) | 1fbcf153e3 | |
Yichun Zhang (agentzh) | da979a620a | |
Yichun Zhang (agentzh) | e75b5c926b | |
Yichun Zhang (agentzh) | 0a35dfc126 | |
Yichun Zhang (agentzh) | 88b4cf1abf | |
Yichun Zhang (agentzh) | 51d68caaed | |
Yichun Zhang (agentzh) | 2a1b28da1c | |
Yichun Zhang (agentzh) | ba4d3dd99f | |
Yichun Zhang (agentzh) | ec3186ccc9 | |
Yichun Zhang (agentzh) | e1cfbe09ab | |
Yichun Zhang (agentzh) | 8caa177718 | |
Yichun Zhang (agentzh) | d00f1e1ef0 | |
Yichun Zhang (agentzh) | ba6621b12b | |
Yichun Zhang (agentzh) | df41967474 | |
Yichun Zhang (agentzh) | 2fd117c427 | |
Yichun Zhang (agentzh) | cfc14f5d26 | |
Yichun Zhang (agentzh) | 1197fe2bd1 | |
Yichun Zhang (agentzh) | b0654629a9 | |
Yichun Zhang (agentzh) | 4fb4791107 | |
Yichun Zhang (agentzh) | 6b82ea1099 | |
Yichun Zhang (agentzh) | b59ef879a5 | |
Yichun Zhang (agentzh) | 2044681992 | |
David Galeano | ee90152ae3 | |
陈小玉 | 7a5c96d72f | |
Thibault Charbonnier | b490cfeea4 | |
Yichun Zhang (agentzh) | b1c4280777 | |
Yichun Zhang (agentzh) | 710d9e323d | |
Yichun Zhang (agentzh) | 1ad7b03044 | |
Yichun Zhang (agentzh) | b6c362bbf6 | |
Yichun Zhang (agentzh) | b03099b386 | |
Yichun Zhang (agentzh) | cbfbd19460 | |
Yichun Zhang (agentzh) | e921c6e9b1 | |
Yichun Zhang (agentzh) | 365c7d9d9e | |
Yichun Zhang (agentzh) | 5d01a5e0b4 | |
Yichun Zhang (agentzh) | e478681308 | |
Yichun Zhang (agentzh) | e254c3d0c1 | |
Yichun Zhang (agentzh) | dbccee1418 | |
Yichun Zhang (agentzh) | efe10e532c | |
Yichun Zhang (agentzh) | 6343d26c17 | |
Yichun Zhang (agentzh) | 8ffd932b20 | |
Yichun Zhang (agentzh) | 6cb4ae0de3 | |
Yichun Zhang (agentzh) | 6c8f4f87ba | |
Yichun Zhang (agentzh) | d7f84c9079 | |
Yichun Zhang (agentzh) | 4f2bf44aba | |
Yichun Zhang (agentzh) | a4640d68f1 | |
Yichun Zhang (agentzh) | 69803153aa | |
Yichun Zhang (agentzh) | b488540a2f | |
Yichun Zhang (agentzh) | b37d406423 | |
Yichun Zhang (agentzh) | dc03e7641b | |
Yichun Zhang (agentzh) | 2900286149 | |
Yichun Zhang (agentzh) | b1c3587c50 | |
Yichun Zhang (agentzh) | 5163293260 | |
Yichun Zhang (agentzh) | 1815637613 | |
Yichun Zhang (agentzh) | fd667d6369 | |
Yichun Zhang (agentzh) | ae8e36ae77 | |
Yichun Zhang (agentzh) | e2a735c481 | |
Yichun Zhang (agentzh) | 7571924cd2 | |
Yichun Zhang (agentzh) | abd91310df | |
Yichun Zhang (agentzh) | edcdb450f4 | |
Yichun Zhang (agentzh) | ed140425aa | |
Yichun Zhang (agentzh) | 949ad066d6 | |
Yichun Zhang (agentzh) | a0e7a6a9fa | |
Yichun Zhang (agentzh) | 45700de84a | |
Yichun Zhang (agentzh) | 8269bbfb3a | |
Yichun Zhang (agentzh) | 6c5e27c40e | |
Yichun Zhang (agentzh) | d7d0d17a2f | |
Yichun Zhang (agentzh) | be80ceb08b | |
Yichun Zhang (agentzh) | e2fa208541 | |
Yichun Zhang (agentzh) | 7321a6af98 | |
Yichun Zhang (agentzh) | 6973ad7234 | |
Yichun Zhang (agentzh) | 5c57aed170 | |
Yichun Zhang (agentzh) | 4253dd2b90 | |
Yichun Zhang (agentzh) | 381697b884 | |
Yichun Zhang (agentzh) | 97901f3357 | |
Yichun Zhang (agentzh) | 09ca92f51f | |
Yichun Zhang (agentzh) | bf0e5bdef0 | |
Yichun Zhang (agentzh) | 961eb11536 | |
Yichun Zhang (agentzh) | 697bb0a08c | |
Yichun Zhang (agentzh) | 9455250873 | |
Yichun Zhang (agentzh) | 5429150ab6 | |
Yichun Zhang (agentzh) | 8d76d5910f | |
Yichun Zhang (agentzh) | 9fa2d93c6b | |
Yichun Zhang (agentzh) | 99f0618218 | |
Yichun Zhang (agentzh) | 7c274e056e | |
Yichun Zhang (agentzh) | 8d8a2529ad | |
Yichun Zhang (agentzh) | 2369d00d46 | |
Yichun Zhang (agentzh) | e9c8fb30f2 | |
Yichun Zhang (agentzh) | e63984f81d | |
Yichun Zhang (agentzh) | 7ce3d4e881 | |
Yichun Zhang (agentzh) | 20c164f5e7 | |
Yichun Zhang (agentzh) | 568d1e0e5d | |
Yichun Zhang (agentzh) | 0e9ed23bf5 | |
Yichun Zhang (agentzh) | d3506c60aa | |
Yichun Zhang (agentzh) | f05b909f11 | |
Yichun Zhang (agentzh) | b321c89392 | |
Yichun Zhang (agentzh) | c47aef193f | |
Yichun Zhang (agentzh) | d6a8907fc0 | |
Yichun Zhang (agentzh) | bf47ba9529 | |
Yichun Zhang (agentzh) | b603282bd6 | |
Yichun Zhang (agentzh) | a6c3a0f21e | |
Yichun Zhang (agentzh) | 7123e4f0df | |
Yichun Zhang (agentzh) | a924c2d9aa | |
Yichun Zhang (agentzh) | 05dc2dc32a | |
Yichun Zhang (agentzh) | 8091435d3f | |
Yichun Zhang (agentzh) | d4d2397011 | |
Yichun Zhang (agentzh) | c7ec3e0b5b | |
Yichun Zhang (agentzh) | b01018e897 | |
Yichun Zhang (agentzh) | 9ef51f89be | |
Yichun Zhang (agentzh) | 853c13c46f | |
Yichun Zhang (agentzh) | 33cf50beae | |
Yichun Zhang (agentzh) | d2e85ffb13 | |
Yichun Zhang (agentzh) | 64971a1336 | |
Yichun Zhang (agentzh) | 57924dc487 | |
Yichun Zhang (agentzh) | 592aa6fec5 | |
Yichun Zhang (agentzh) | 5edc89c7be | |
Yichun Zhang (agentzh) | 665faf0aea | |
Yichun Zhang (agentzh) | 07dc137193 | |
Yichun Zhang (agentzh) | 20a6484f71 | |
Yichun Zhang (agentzh) | e4af1abdc3 | |
Yichun Zhang (agentzh) | 6229590201 | |
Yichun Zhang (agentzh) | 5ca7a403b9 | |
Yichun Zhang (agentzh) | d915ad9427 | |
Yichun Zhang (agentzh) | d0b0e7e1fc | |
Yichun Zhang (agentzh) | 57984e23f8 | |
Yichun Zhang (agentzh) | 03ec98a39e | |
Yichun Zhang (agentzh) | 63e116b90b | |
Yichun Zhang (agentzh) | a98bfe8325 | |
Yichun Zhang (agentzh) | 7af6c9b12c | |
Yichun Zhang (agentzh) | 9dd706ad03 | |
Yichun Zhang (agentzh) | 2589f0d3c1 | |
Yichun Zhang (agentzh) | 0e2f55d2a0 | |
Yichun Zhang (agentzh) | 6160254ec8 | |
Yichun Zhang (agentzh) | d836ee1e8e | |
Yichun Zhang (agentzh) | fb040b60db | |
Yichun Zhang (agentzh) | 7f5a1fa7e4 | |
Yichun Zhang (agentzh) | 7a2e4881b8 | |
Yichun Zhang (agentzh) | bdaea38b7d | |
Yichun Zhang (agentzh) | 741ff983e8 | |
Yichun Zhang (agentzh) | a9cada5c27 | |
Yichun Zhang (agentzh) | 1b197fb27a | |
Yichun Zhang (agentzh) | 86be514b1c | |
Yichun Zhang (agentzh) | 3041624fbc | |
Yichun Zhang (agentzh) | de75e4d7ed | |
Yichun Zhang (agentzh) | 107847d6fd | |
Yichun Zhang (agentzh) | 36bafb83ed | |
Yichun Zhang (agentzh) | f4ca954418 | |
Yichun Zhang (agentzh) | 6f8aba9da3 | |
Yichun Zhang (agentzh) | 2436ab0b8c | |
Yichun Zhang (agentzh) | c05b97fcad | |
Yichun Zhang (agentzh) | 6dd13af2a1 | |
Yichun Zhang (agentzh) | aa6c86f46a | |
Yichun Zhang (agentzh) | 74940ddd15 | |
Yichun Zhang (agentzh) | 7d9e51e1b3 | |
Yichun Zhang (agentzh) | e4cfb92295 | |
Yichun Zhang (agentzh) | 7f9675a005 | |
Yichun Zhang (agentzh) | 71ece286fa | |
Yichun Zhang (agentzh) | 54c2766d1c | |
Yichun Zhang (agentzh) | 3da92ac16c | |
Yichun Zhang (agentzh) | 463a6a14ee | |
Yichun Zhang (agentzh) | 5f7f678876 | |
Yichun Zhang (agentzh) | 753ef7074b | |
Yichun Zhang (agentzh) | 8c6b0f77af | |
Yichun Zhang (agentzh) | 52962f3fc9 | |
Yichun Zhang (agentzh) | 0e31ce1662 | |
Yichun Zhang (agentzh) | da90bd7671 | |
Yichun Zhang (agentzh) | 4a80309873 | |
Yichun Zhang (agentzh) | 383901b193 | |
Yichun Zhang (agentzh) | 9bd838251f | |
Yichun Zhang (agentzh) | e5fd373848 | |
Yichun Zhang (agentzh) | db38504310 | |
Yichun Zhang (agentzh) | 2351c7c7aa | |
Yichun Zhang (agentzh) | f3d36df365 | |
Yichun Zhang (agentzh) | 220b940e66 | |
Yichun Zhang (agentzh) | c0c2f883e9 | |
Yichun Zhang (agentzh) | 9cf02ba0c0 | |
Yichun Zhang (agentzh) | 5760ca8dee | |
Yichun Zhang (agentzh) | e1b492fc18 | |
Yichun Zhang (agentzh) | cada794d74 | |
Yichun Zhang (agentzh) | ec162777c3 | |
Yichun Zhang (agentzh) | a9a8ebee7a | |
Yichun Zhang (agentzh) | ac4d52423c | |
Yichun Zhang (agentzh) | c0a85e7e3e | |
Yichun Zhang (agentzh) | c64ff34957 | |
Yichun Zhang (agentzh) | 54b824d1f4 | |
Yichun Zhang (agentzh) | cdedd89613 | |
Yichun Zhang (agentzh) | 8ebc5c5b16 | |
Yichun Zhang (agentzh) | e12c526577 | |
Yichun Zhang (agentzh) | a78f6e3741 | |
Yichun Zhang (agentzh) | 62cc6b3758 | |
Yichun Zhang (agentzh) | e60f9030ab | |
Yichun Zhang (agentzh) | eb33b0b08f | |
Yichun Zhang (agentzh) | 83eeb14f6c | |
Yichun Zhang (agentzh) | d996a90c14 | |
Yichun Zhang (agentzh) | 584c1a7e12 | |
Yichun Zhang (agentzh) | 3882d2572e | |
Yichun Zhang (agentzh) | ce64259d66 | |
Yichun Zhang (agentzh) | 9b439dde0e | |
Yichun Zhang (agentzh) | ed8b6996e9 | |
Yichun Zhang (agentzh) | 5fc5745de0 | |
Yichun Zhang (agentzh) | d55f45c7ff | |
Yichun Zhang (agentzh) | cba6fbd864 | |
Yichun Zhang (agentzh) | caea3438eb | |
Yichun Zhang (agentzh) | cde439a55a | |
Yichun Zhang (agentzh) | 38abb277b5 | |
Yichun Zhang (agentzh) | 1c106bf487 | |
Yichun Zhang (agentzh) | 3cacb62a10 | |
Yichun Zhang (agentzh) | 4374e25548 | |
Yichun Zhang (agentzh) | 0e95be39c1 | |
Yichun Zhang (agentzh) | d68403407d | |
Yichun Zhang (agentzh) | f5329c7781 | |
Yichun Zhang (agentzh) | 3ac11ef73c | |
Yichun Zhang (agentzh) | 5db4e19482 | |
Yichun Zhang (agentzh) | fa3af6cdf8 | |
Yichun Zhang (agentzh) | 828a7eec41 | |
Yichun Zhang (agentzh) | 1f4045ef2c | |
Yichun Zhang (agentzh) | 6a17d2c784 | |
Yichun Zhang (agentzh) | 6624c48881 | |
Yichun Zhang (agentzh) | 7f15701e76 | |
Yichun Zhang (agentzh) | 1220e284aa | |
Yichun Zhang (agentzh) | d831e27995 | |
Yichun Zhang (agentzh) | 033b2d88ff | |
Yichun Zhang (agentzh) | 622ddd7bb0 | |
Yichun Zhang (agentzh) | 3e94b37750 | |
Yichun Zhang (agentzh) | 2d0119084e | |
Yichun Zhang (agentzh) | b19b53d6cc | |
Yichun Zhang (agentzh) | 04da1876f0 | |
Yichun Zhang (agentzh) | e82486be60 | |
Yichun Zhang (agentzh) | f84e035e45 | |
Yichun Zhang (agentzh) | c02caa3587 | |
Yichun Zhang (agentzh) | 24eed036c5 | |
Yichun Zhang (agentzh) | 87c988e4ba | |
Yichun Zhang (agentzh) | 46881fd2dc | |
Yichun Zhang (agentzh) | 4907d14700 | |
Yichun Zhang (agentzh) | 60e72cbf82 | |
Yichun Zhang (agentzh) | 97a05513eb | |
Yichun Zhang (agentzh) | 7d0443d5d7 | |
Yichun Zhang (agentzh) | ce65738299 | |
Yichun Zhang (agentzh) | 2871ccb9ac | |
Yichun Zhang (agentzh) | aab5001ffc | |
Yichun Zhang (agentzh) | 53952e347e | |
Yichun Zhang (agentzh) | 19de4329b8 | |
Yichun Zhang | af48ac42d5 | |
Vic Vijayakumar | 126786276b | |
Yichun Zhang (agentzh) | ffb5acf592 | |
Yichun Zhang (agentzh) | 9bcdd4b62f | |
Yichun Zhang (agentzh) | b0a74456ba | |
Yichun Zhang (agentzh) | 357bb4a977 | |
Yichun Zhang (agentzh) | 3ddbf6f8d4 | |
Yichun Zhang (agentzh) | e1b680f985 | |
Yichun Zhang (agentzh) | 389f3a8041 | |
Yichun Zhang (agentzh) | 2d6112943f | |
Yichun Zhang (agentzh) | 99d5e37f3b | |
Yichun Zhang (agentzh) | f57f48f6ce | |
Yichun Zhang (agentzh) | d332766a3f | |
Yichun Zhang (agentzh) | 2e5d8d5179 | |
Yichun Zhang (agentzh) | 9295450eb8 | |
Yichun Zhang (agentzh) | 73db05ca54 | |
Yichun Zhang (agentzh) | a7f1816ba1 | |
Yichun Zhang (agentzh) | 613241d40d | |
Yichun Zhang (agentzh) | fc386017f3 | |
Yichun Zhang (agentzh) | b1f99a6156 | |
Yichun Zhang (agentzh) | fec2e0249c | |
Yichun Zhang (agentzh) | d225abe6d1 | |
Yichun Zhang (agentzh) | 5df64b4e63 | |
Yichun Zhang (agentzh) | 78dd9dbc23 | |
Yichun Zhang (agentzh) | ca9a9824d5 | |
Yichun Zhang (agentzh) | 42d53db5b9 | |
Yichun Zhang (agentzh) | 441cee68b1 | |
Yichun Zhang (agentzh) | 58c89f206d | |
Yichun Zhang (agentzh) | 1f7f6a31b2 | |
Yichun Zhang (agentzh) | 795f52d06c | |
Yichun Zhang (agentzh) | c01de73e41 | |
Yichun Zhang (agentzh) | 387089ca11 | |
Yichun Zhang (agentzh) | d66f8b699f | |
Yichun Zhang (agentzh) | b75e8490c2 | |
Yichun Zhang (agentzh) | 30c2d1bde6 | |
Yichun Zhang (agentzh) | dc2cd9b9e5 | |
Yichun Zhang (agentzh) | c04635fbd7 | |
Yichun Zhang (agentzh) | 667802cee6 | |
Yichun Zhang (agentzh) | ee28a12949 | |
Yichun Zhang (agentzh) | 99ca550104 | |
Yichun Zhang (agentzh) | 6be51e769a | |
Yichun Zhang (agentzh) | 6142b6936f | |
Yichun Zhang (agentzh) | 86ba1e09f4 | |
Yichun Zhang (agentzh) | 2519cd7dd3 | |
Yichun Zhang (agentzh) | 3ae5c4d93e | |
Yichun Zhang (agentzh) | e82793361b | |
Yichun Zhang (agentzh) | 55909727dd | |
Yichun Zhang (agentzh) | 6b052c8fca | |
Yichun Zhang (agentzh) | fab852190b | |
Yichun Zhang (agentzh) | dc007ebcb9 | |
Yichun Zhang (agentzh) | f46cfc667d | |
Yichun Zhang (agentzh) | 5f6a50cacc | |
Yichun Zhang (agentzh) | 16d0b04e1c | |
Yichun Zhang (agentzh) | 076f2bd45e | |
Yichun Zhang (agentzh) | b1a852b27e | |
Yichun Zhang (agentzh) | fdcdc15436 | |
Yichun Zhang (agentzh) | 916245656b | |
Yichun Zhang (agentzh) | 03b25469c8 | |
Yichun Zhang (agentzh) | b70fdea626 | |
Yichun Zhang (agentzh) | 8a5b1bb328 | |
Yichun Zhang (agentzh) | 47bf7e9349 | |
Yichun Zhang (agentzh) | 3b6bfca045 | |
Yichun Zhang (agentzh) | 11b10b4e7b | |
Yichun Zhang (agentzh) | a953967d88 | |
Yichun Zhang (agentzh) | ab169da35b | |
Yichun Zhang (agentzh) | b06e150af4 | |
Yichun Zhang (agentzh) | 706823455a | |
Yichun Zhang (agentzh) | 1d15d9e393 | |
Yichun Zhang (agentzh) | 3d674b8635 | |
Yichun Zhang (agentzh) | 94d38e3ff7 | |
Yichun Zhang (agentzh) | 80bc3c3549 | |
Yichun Zhang (agentzh) | 5cb6e4f591 | |
Yichun Zhang (agentzh) | b6d3a5cf7b | |
Yichun Zhang (agentzh) | 46a5fd3bba | |
Yichun Zhang (agentzh) | c474f54723 | |
Yichun Zhang (agentzh) | f318ad5c7e | |
Yichun Zhang (agentzh) | 065fb6db35 | |
Yichun Zhang (agentzh) | 0aeef4f31a | |
Yichun Zhang (agentzh) | 640108c6f5 | |
Yichun Zhang (agentzh) | 445ca90f06 | |
Yichun Zhang (agentzh) | dde4c94fd0 | |
Yichun Zhang (agentzh) | 6facf67420 | |
Yichun Zhang (agentzh) | 8dae181c24 | |
Yichun Zhang (agentzh) | 2a2c1269b0 | |
Yichun Zhang (agentzh) | b2cc655554 | |
Yichun Zhang (agentzh) | 07913609c6 | |
Yichun Zhang (agentzh) | c7eea80684 | |
Yichun Zhang (agentzh) | 9a26a0452d | |
Yichun Zhang (agentzh) | 4fed7a2d05 | |
Yichun Zhang (agentzh) | e2a964d124 | |
Yichun Zhang (agentzh) | 0bfb73764e | |
Yichun Zhang (agentzh) | 85f9313252 | |
Yichun Zhang (agentzh) | cf8c075e79 | |
Yichun Zhang (agentzh) | bb71a30a68 | |
Yichun Zhang (agentzh) | af058d15db | |
Yichun Zhang (agentzh) | 59e6665224 | |
Yichun Zhang (agentzh) | fae163cc70 | |
Yichun Zhang (agentzh) | fd1f99ff52 | |
Yichun Zhang (agentzh) | 1140a2fa67 | |
Yichun Zhang (agentzh) | 6f26127d9b | |
Yichun Zhang (agentzh) | 96fc664875 | |
Yichun Zhang (agentzh) | f7e34420c0 | |
Yichun Zhang (agentzh) | 399bdecaef | |
Yichun Zhang (agentzh) | aa33a9e752 | |
Yichun Zhang (agentzh) | c8b64f9fd4 | |
Yichun Zhang (agentzh) | 1429569342 | |
Yichun Zhang (agentzh) | 88f0bdb2ae | |
Yichun Zhang (agentzh) | 526c35ce2f | |
Yichun Zhang (agentzh) | 5b6c063ae7 | |
Yichun Zhang (agentzh) | 34f66f5343 | |
Yichun Zhang (agentzh) | 471940c09b | |
Yichun Zhang (agentzh) | c9c42f0fee | |
Yichun Zhang (agentzh) | 1b20094c21 | |
Yichun Zhang (agentzh) | fed9b15524 | |
Yichun Zhang (agentzh) | 51a7b54c60 | |
Yichun Zhang (agentzh) | a90eb927f5 | |
Yichun Zhang (agentzh) | 8da3363507 | |
Yichun Zhang (agentzh) | 9d3aa49228 | |
Yichun Zhang (agentzh) | 1266a2933e | |
Yichun Zhang (agentzh) | e225c37731 | |
Yichun Zhang (agentzh) | b7f6be5a2f | |
Yichun Zhang (agentzh) | c23007bcce | |
Yichun Zhang (agentzh) | 867328aa81 | |
Yichun Zhang (agentzh) | cd89141e48 | |
Yichun Zhang (agentzh) | 43ae08a6c4 | |
Yichun Zhang (agentzh) | f26ae39115 | |
Yichun Zhang (agentzh) | cc4a307f0e | |
Yichun Zhang (agentzh) | 315279079f | |
Yichun Zhang (agentzh) | 6d854671b7 | |
Yichun Zhang (agentzh) | 88500d7328 | |
Yichun Zhang (agentzh) | da19bb5a49 | |
Yichun Zhang (agentzh) | 58b1cf3443 | |
Yichun Zhang (agentzh) | a485e40fb8 | |
Yichun Zhang (agentzh) | b92c497d19 | |
Yichun Zhang (agentzh) | e6985ae696 | |
Yichun Zhang (agentzh) | 98d4b7ef1f | |
Yichun Zhang (agentzh) | b1f221b066 | |
Yichun Zhang (agentzh) | 217b21e928 | |
Yichun Zhang (agentzh) | 9b656b9c5e | |
Yichun Zhang (agentzh) | ee61517201 | |
Yichun Zhang (agentzh) | 6eaf60aa1c | |
Yichun Zhang (agentzh) | 3dfbe11054 | |
Yichun Zhang (agentzh) | 185f8cacfa | |
Yichun Zhang (agentzh) | e4a932b5cb | |
Yichun Zhang (agentzh) | ca534abb8f | |
Yichun Zhang (agentzh) | bfc6b755b0 | |
Yichun Zhang (agentzh) | c08b4a0493 | |
Yichun Zhang (agentzh) | 9e5299a0d2 | |
Yichun Zhang (agentzh) | b824a3cb59 | |
Yichun Zhang (agentzh) | 6e41bcd018 | |
Yichun Zhang (agentzh) | 62633cfa8d | |
Yichun Zhang (agentzh) | cd74a45f39 | |
Yichun Zhang (agentzh) | bc3cb9243f | |
Yichun Zhang (agentzh) | 20ace16258 | |
Yichun Zhang (agentzh) | b54113f517 | |
Yichun Zhang (agentzh) | 39407386ea | |
Yichun Zhang (agentzh) | f1f3ba8ec6 | |
Yichun Zhang (agentzh) | e37973502e | |
Yichun Zhang (agentzh) | 4085b21eb8 | |
Yichun Zhang (agentzh) | 91484d0e11 | |
Yichun Zhang (agentzh) | f5d5e5a2fa | |
Yichun Zhang (agentzh) | 1e7d38d479 | |
Yichun Zhang (agentzh) | 52e622a26c | |
Yichun Zhang (agentzh) | 20e69718ce | |
Yichun Zhang (agentzh) | 05334f1b5b | |
Yichun Zhang (agentzh) | 91549c16b4 | |
Yichun Zhang (agentzh) | 1dbd0b24d2 | |
Yichun Zhang (agentzh) | 9c3a123035 | |
Yichun Zhang (agentzh) | 2ee8fe558a | |
Yichun Zhang (agentzh) | 6ab944ebc4 | |
Yichun Zhang (agentzh) | 332a42f57f | |
Yichun Zhang (agentzh) | 60bc64a72a | |
Yichun Zhang (agentzh) | e3b7de9b23 | |
Yichun Zhang (agentzh) | c2fb3c9dac | |
Yichun Zhang (agentzh) | 84f0092a6c | |
Yichun Zhang (agentzh) | 8cd9200a0f | |
Yichun Zhang (agentzh) | 5d4854f3e9 | |
Yichun Zhang (agentzh) | b6661ea47c | |
Yichun Zhang (agentzh) | c9b0947bbb | |
Yichun Zhang (agentzh) | 77104b6cdf | |
Yichun Zhang (agentzh) | e932c8a136 | |
Yichun Zhang (agentzh) | 10fd3ea365 | |
Yichun Zhang (agentzh) | 303601ef8c | |
Yichun Zhang (agentzh) | 7f377fd354 | |
Yichun Zhang (agentzh) | fdad0c63ce | |
Yichun Zhang (agentzh) | b0f1e786c1 | |
Yichun Zhang (agentzh) | d001d17d0c | |
Yichun Zhang (agentzh) | 37ba2b1015 | |
Yichun Zhang (agentzh) | d21cc33749 | |
Yichun Zhang (agentzh) | 2ba03387fd | |
Yichun Zhang (agentzh) | 03eae9e632 | |
Yichun Zhang (agentzh) | 965bd0fba0 | |
Yichun Zhang (agentzh) | f8783f35b1 | |
Yichun Zhang (agentzh) | e36d505d80 | |
Yichun Zhang (agentzh) | 3ddc73ac43 | |
Yichun Zhang (agentzh) | 35934abdb1 | |
Yichun Zhang (agentzh) | 5836469559 | |
Yichun Zhang (agentzh) | 925156bb2b | |
Yichun Zhang (agentzh) | 1a8bffaf7a | |
Yichun Zhang (agentzh) | df3547fccd | |
Yichun Zhang (agentzh) | 3b078c75ae | |
Yichun Zhang (agentzh) | 227e4e0da2 | |
Yichun Zhang (agentzh) | 676150c81b | |
Yichun Zhang (agentzh) | 5c14faf444 | |
Yichun Zhang (agentzh) | 84f46c7be5 | |
Yichun Zhang (agentzh) | 65367a71cd | |
Yichun Zhang (agentzh) | 5e9a5cdc95 | |
Yichun Zhang (agentzh) | 85d38c49a2 | |
Yichun Zhang (agentzh) | 486b212269 | |
Yichun Zhang (agentzh) | c1fb5194ef | |
Yichun Zhang (agentzh) | 87e5f34a9d | |
Yichun Zhang (agentzh) | e85568e044 | |
Yichun Zhang (agentzh) | d093c84c8e | |
Yichun Zhang (agentzh) | 613d5ad058 | |
Yichun Zhang (agentzh) | 0794f667d6 | |
Yichun Zhang (agentzh) | c9d9e4a8dd | |
Yichun Zhang (agentzh) | f830a55d2d | |
Yichun Zhang (agentzh) | 2904556700 | |
Yichun Zhang (agentzh) | 1c9f799fa6 | |
Yichun Zhang (agentzh) | 9a3e9dbffd | |
Yichun Zhang (agentzh) | 793c541c45 | |
Yichun Zhang (agentzh) | b7348233e8 | |
Yichun Zhang (agentzh) | 6dc6ba72d5 | |
Yichun Zhang (agentzh) | 1eb135cc6a | |
Yichun Zhang (agentzh) | 4bab759ea3 | |
Yichun Zhang (agentzh) | 8cec47f755 | |
Yichun Zhang (agentzh) | 02614af5ed | |
Yichun Zhang (agentzh) | 163432a678 | |
Yichun Zhang (agentzh) | c338e4d0e2 | |
Yichun Zhang (agentzh) | 374f575dfa | |
Yichun Zhang (agentzh) | b53c539f7e | |
Yichun Zhang (agentzh) | a16a33d417 | |
Yichun Zhang (agentzh) | e3e60a3a68 | |
Yichun Zhang (agentzh) | 71a675f4fb | |
Yichun Zhang (agentzh) | adb00e91e7 | |
Yichun Zhang (agentzh) | c6aad4deba | |
Yichun Zhang (agentzh) | b8bf7bbb4c | |
Yichun Zhang (agentzh) | 0528788543 | |
Yichun Zhang (agentzh) | 378f94fb58 | |
Yichun Zhang (agentzh) | 5be3b51678 | |
Yichun Zhang (agentzh) | 2fb9ed5c1d | |
Yichun Zhang (agentzh) | 1728ca8c66 | |
Yichun Zhang (agentzh) | 157febe350 | |
Yichun Zhang (agentzh) | 633abb71bf | |
Yichun Zhang (agentzh) | 8b86c72ea2 | |
Yichun Zhang (agentzh) | 97622943d2 | |
Yichun Zhang (agentzh) | 383ed9a47d | |
Yichun Zhang (agentzh) | bd81be02ee | |
Yichun Zhang (agentzh) | fa917e6620 | |
Yichun Zhang (agentzh) | b694456ef3 | |
Yichun Zhang (agentzh) | 95d727fd8f | |
Yichun Zhang (agentzh) | a860e4192c | |
Yichun Zhang (agentzh) | 68d1241d12 | |
Yichun Zhang (agentzh) | 73201a29f7 | |
Yichun Zhang (agentzh) | 6522b3420c | |
Yichun Zhang (agentzh) | 360aaab086 | |
Yichun Zhang (agentzh) | 78cca18fef | |
Yichun Zhang (agentzh) | a06c2308e1 | |
Yichun Zhang (agentzh) | d919948850 | |
Yichun Zhang (agentzh) | cd3b7f3bfb | |
Yichun Zhang (agentzh) | d846011a3e | |
Yichun Zhang (agentzh) | e4ff7dbfac | |
Yichun Zhang (agentzh) | f35f66a487 | |
Yichun Zhang (agentzh) | aac5d5e49e | |
Yichun Zhang (agentzh) | 8bc4bf391a | |
Yichun Zhang (agentzh) | 1df484be52 | |
Yichun Zhang (agentzh) | 4308a5ca45 | |
Yichun Zhang (agentzh) | 274b1b6778 | |
Yichun Zhang (agentzh) | 2d3ff6af97 | |
Yichun Zhang (agentzh) | 5f7b64e17a | |
Yichun Zhang (agentzh) | 4513cad926 | |
Yichun Zhang (agentzh) | a7c39891c6 | |
Yichun Zhang (agentzh) | 35e053cb6c | |
Yichun Zhang (agentzh) | ae74836236 | |
Yichun Zhang (agentzh) | b0d3505b31 | |
Yichun Zhang (agentzh) | 9d2ae2e217 | |
Yichun Zhang (agentzh) | 6bb19476b4 | |
Yichun Zhang (agentzh) | f0a2f6543e | |
Yichun Zhang (agentzh) | 937985fc03 | |
Yichun Zhang (agentzh) | 457d0526ea | |
Yichun Zhang (agentzh) | f0243eb2aa | |
Yichun Zhang (agentzh) | 76a803640a | |
Yichun Zhang (agentzh) | 5fe07d1df5 | |
Yichun Zhang (agentzh) | 2c23a0859e | |
Yichun Zhang (agentzh) | 8012da1f61 | |
Yichun Zhang (agentzh) | e0d777bb5d | |
Yichun Zhang (agentzh) | 37737082dd | |
Yichun Zhang (agentzh) | 5c77ae9d4a | |
Yichun Zhang (agentzh) | 2d2132d232 | |
Yichun Zhang (agentzh) | 559f187c3c | |
Yichun Zhang (agentzh) | 609e375e66 | |
Yichun Zhang (agentzh) | e84b9d0175 | |
Yichun Zhang (agentzh) | 221130defc | |
Yichun Zhang (agentzh) | 921fd6d675 | |
Yichun Zhang (agentzh) | c36f990f10 | |
Yichun Zhang (agentzh) | b3ed109998 | |
Yichun Zhang (agentzh) | 3d547529fd | |
Yichun Zhang (agentzh) | d0834f8cd9 | |
Yichun Zhang (agentzh) | 5f2ede4fd2 | |
Yichun Zhang (agentzh) | 0222649b03 | |
Yichun Zhang (agentzh) | 320c5008e4 | |
Yichun Zhang (agentzh) | a4006329a7 | |
Yichun Zhang (agentzh) | 2890410b68 | |
Yichun Zhang (agentzh) | 197399d1b6 | |
Yichun Zhang (agentzh) | 54f86fd361 | |
Yichun Zhang (agentzh) | 110c8fe4ce | |
Yichun Zhang (agentzh) | a825570875 | |
Yichun Zhang (agentzh) | 2bfd01ed14 | |
Yichun Zhang (agentzh) | 49599affe9 | |
Yichun Zhang (agentzh) | 96abf202e4 | |
Yichun Zhang (agentzh) | 6f31d3b261 | |
Yichun Zhang (agentzh) | cee1aca97f | |
Yichun Zhang (agentzh) | b9325c34d8 | |
Yichun Zhang (agentzh) | a169416e71 | |
Yichun Zhang (agentzh) | cef62e1aa8 | |
agentzh (Yichun Zhang) | bb367bc9e6 | |
agentzh (Yichun Zhang) | 3a7529d7d0 | |
agentzh (Yichun Zhang) | 4cdd11476b | |
agentzh (Yichun Zhang) | c312ba38b3 | |
agentzh (Yichun Zhang) | 5328f0113f | |
agentzh (Yichun Zhang) | b9eb443da6 | |
agentzh (Yichun Zhang) | 72da5ad7ba | |
agentzh (Yichun Zhang) | ac3b864532 | |
agentzh (Yichun Zhang) | 6c14ea5c56 | |
agentzh (Yichun Zhang) | b68ec13a71 | |
agentzh (Yichun Zhang) | 76f2f6c2f3 | |
agentzh (Yichun Zhang) | a5c4d85835 | |
agentzh (Yichun Zhang) | 24d8c2265e | |
agentzh (Yichun Zhang) | d9a491a88c | |
agentzh (Yichun Zhang) | 6ce2a28c23 | |
agentzh (Yichun Zhang) | 07fbdad118 | |
agentzh (Yichun Zhang) | ca9f8d0622 | |
agentzh (Yichun Zhang) | 090060c907 | |
agentzh (Yichun Zhang) | b156d2db62 | |
agentzh (Yichun Zhang) | dbb9c98bee | |
agentzh (Yichun Zhang) | 4c300f618d | |
agentzh (Yichun Zhang) | 62bbc5c4c5 | |
agentzh (Yichun Zhang) | 529f4c854c | |
agentzh (Yichun Zhang) | 3a873d7874 | |
agentzh (Yichun Zhang) | aadd93ff24 | |
agentzh (Yichun Zhang) | bae91cc5c4 | |
agentzh (Yichun Zhang) | ea1d378e84 | |
agentzh (章亦春) | ed2f8de61a | |
agentzh (Yichun Zhang) | 1d096c047e | |
agentzh (Yichun Zhang) | 1bfc510257 | |
agentzh (Yichun Zhang) | 9f0143b14f | |
agentzh (Yichun Zhang) | 05ae54a092 | |
agentzh (Yichun Zhang) | 09598a3e19 | |
agentzh (Yichun Zhang) | 977c5b1d51 | |
agentzh (Yichun Zhang) | 6063956a1a | |
agentzh (Yichun Zhang) | e91766c012 | |
agentzh (Yichun Zhang) | a2ed0a0403 | |
agentzh (Yichun Zhang) | 8e57e2541b | |
agentzh (Yichun Zhang) | f5f2d672e7 | |
agentzh (Yichun Zhang) | 49d9d9b778 | |
agentzh (Yichun Zhang) | 13efb24106 | |
agentzh (Yichun Zhang) | 3be0b7f0e1 | |
agentzh (Yichun Zhang) | 5fb8647d23 | |
agentzh (Yichun Zhang) | e7053c9ca9 | |
agentzh (Yichun Zhang) | 042e2fd27b | |
agentzh (Yichun Zhang) | 1d909539a8 | |
agentzh (Yichun Zhang) | d54e2dcc69 | |
agentzh (Yichun Zhang) | 009db177df | |
agentzh (Yichun Zhang) | 7e359ff049 | |
agentzh (Yichun Zhang) | 9f52ad4a45 | |
agentzh (Yichun Zhang) | a925be09c9 | |
agentzh (Yichun Zhang) | d91993fc38 | |
agentzh (Yichun Zhang) | 0a9a7012dc | |
agentzh (Yichun Zhang) | c9f5ca8566 | |
agentzh (Yichun Zhang) | 7495a32ec2 | |
agentzh (Yichun Zhang) | 9e944b8c53 | |
agentzh (Yichun Zhang) | b259f33198 | |
agentzh (Yichun Zhang) | db978031d2 | |
agentzh (Yichun Zhang) | 1ca5fb8597 | |
agentzh (Yichun Zhang) | 8496c99def | |
agentzh (Yichun Zhang) | f1083d82d4 | |
agentzh (Yichun Zhang) | dd4620afaf | |
agentzh (Yichun Zhang) | 45c5114e9d | |
agentzh (Yichun Zhang) | a553009af0 | |
agentzh (Yichun Zhang) | ed74e3d767 | |
agentzh (Yichun Zhang) | c0208b8c40 | |
agentzh (Yichun Zhang) | 2681361df1 | |
agentzh (Yichun Zhang) | 0a2dcd7c50 | |
agentzh (Yichun Zhang) | 3e5b0eeee3 | |
agentzh (Yichun Zhang) | 42d640985e | |
agentzh (Yichun Zhang) | 8e35463045 | |
agentzh (Yichun Zhang) | fc1929f37d | |
agentzh (Yichun Zhang) | 6d0cbed3f7 | |
agentzh (Yichun Zhang) | 9e4d2c03cf | |
agentzh (Yichun Zhang) | 1faf158381 | |
agentzh (Yichun Zhang) | a820d40858 | |
agentzh (Yichun Zhang) | 7569b78aeb | |
agentzh (Yichun Zhang) | 1da1181ba1 | |
agentzh (Yichun Zhang) | 06d3586e95 | |
agentzh (Yichun Zhang) | 309f0cf7ad | |
agentzh (Yichun Zhang) | a31b1d0118 | |
agentzh (Yichun Zhang) | f2b37bbcc7 | |
agentzh (Yichun Zhang) | a841caaff8 | |
agentzh (Yichun Zhang) | 1b425e82b6 | |
agentzh (Yichun Zhang) | d0d058410b | |
agentzh (Yichun Zhang) | 3f212924cf | |
agentzh (Yichun Zhang) | f936d06933 | |
agentzh (Yichun Zhang) | bdc3c5e077 | |
agentzh (Yichun Zhang) | 5e881d7591 | |
agentzh (Yichun Zhang) | eabcfb4369 | |
agentzh (Yichun Zhang) | 300b788e88 | |
agentzh (Yichun Zhang) | 1f83898d01 | |
agentzh (Yichun Zhang) | 31e4baf6ca | |
agentzh (Yichun Zhang) | bb4d9b26fe | |
agentzh (Yichun Zhang) | 2696c9f161 | |
agentzh (Yichun Zhang) | f8eda5d0f4 | |
agentzh (Yichun Zhang) | 2ad093b4fa | |
agentzh (Yichun Zhang) | 774a60c8eb | |
agentzh (Yichun Zhang) | 9e9a6616c1 | |
agentzh (Yichun Zhang) | 46cc366250 | |
agentzh (Yichun Zhang) | 611b828d12 | |
agentzh (Yichun Zhang) | 0ae14ee78a | |
agentzh (Yichun Zhang) | 35b5f534cf | |
agentzh (Yichun Zhang) | 9bd2c1fbc5 | |
agentzh (Yichun Zhang) | d4e5d9967d | |
agentzh (Yichun Zhang) | def1331dea | |
agentzh (Yichun Zhang) | b447ec474e | |
agentzh (Yichun Zhang) | 7265b0920d | |
agentzh (Yichun Zhang) | 67745bc16b | |
agentzh (Yichun Zhang) | 8e724d481b | |
agentzh (Yichun Zhang) | eac1071088 | |
agentzh (Yichun Zhang) | 86a935befc | |
agentzh (Yichun Zhang) | 8950d4655d | |
agentzh (Yichun Zhang) | 7be71ca17b | |
agentzh (Yichun Zhang) | 0e72914300 | |
agentzh (Yichun Zhang) | 6ca011f192 | |
agentzh (Yichun Zhang) | 0602a38652 | |
agentzh (Yichun Zhang) | 2c38f847b9 | |
agentzh (Yichun Zhang) | c0c25af648 | |
agentzh (Yichun Zhang) | ce23e95741 | |
agentzh (Yichun Zhang) | c6f3705301 | |
agentzh (Yichun Zhang) | 3482cb3e20 | |
agentzh (Yichun Zhang) | 500a2053bc | |
agentzh (Yichun Zhang) | 8ead3bebb4 | |
agentzh (Yichun Zhang) | b19a7dfba7 | |
agentzh (Yichun Zhang) | b8bdf87799 | |
agentzh (Yichun Zhang) | 1dd6b50740 | |
agentzh (Yichun Zhang) | 07a3959dd2 | |
agentzh (Yichun Zhang) | 00621a168b | |
agentzh (Yichun Zhang) | 676d24e9d2 | |
agentzh (Yichun Zhang) | 25a4bc42a6 | |
agentzh (Yichun Zhang) | ab224cbfaa | |
agentzh (Yichun Zhang) | eaf795624e | |
agentzh (Yichun Zhang) | 8f25d8997e | |
agentzh (Yichun Zhang) | 4304116026 | |
agentzh (Yichun Zhang) | 72f9765050 | |
agentzh (Yichun Zhang) | af4fb37670 | |
agentzh (Yichun Zhang) | 48b0eac804 | |
agentzh (Yichun Zhang) | 82f6eaa0f4 | |
agentzh (Yichun Zhang) | c381151ce7 | |
agentzh (Yichun Zhang) | e76578edfc | |
agentzh (Yichun Zhang) | e5ba4d313a | |
agentzh (Yichun Zhang) | a5e7da198b | |
agentzh (Yichun Zhang) | b83fb77107 | |
agentzh (Yichun Zhang) | 9e9cf9630c | |
agentzh (Yichun Zhang) | 02153fd2c8 | |
agentzh (Yichun Zhang) | 5ddb48afc3 | |
agentzh (Yichun Zhang) | 6a37c9bfdc | |
agentzh (Yichun Zhang) | 3001c7a52e | |
agentzh (Yichun Zhang) | 0780186565 | |
agentzh (Yichun Zhang) | 84917b7821 | |
agentzh (Yichun Zhang) | 1a90e3fc91 | |
agentzh (Yichun Zhang) | ac3efbbea8 | |
agentzh (Yichun Zhang) | 2629184a0e | |
agentzh (Yichun Zhang) | 62d4082c79 | |
agentzh (Yichun Zhang) | 6c962fb0fb | |
agentzh (Yichun Zhang) | b201032d1e | |
agentzh (Yichun Zhang) | dceae9e8f9 | |
agentzh (Yichun Zhang) | 61ae4da522 | |
agentzh (Yichun Zhang) | 8f9b404c29 | |
agentzh (Yichun Zhang) | ea820f5c9f | |
agentzh (章亦春) | 23ebcbc77a | |
agentzh (Yichun Zhang) | 3e932d8aa8 | |
agentzh (Yichun Zhang) | 01984bab7c | |
agentzh (Yichun Zhang) | 248189c74e | |
agentzh (Yichun Zhang) | 9a7ee9edc5 | |
agentzh (Yichun Zhang) | 81a9a29994 | |
agentzh (Yichun Zhang) | 6f71631c4b | |
agentzh (Yichun Zhang) | 2726586caa | |
agentzh (章亦春) | 654bd20277 | |
agentzh (Yichun Zhang) | afcd9fea37 | |
agentzh (Yichun Zhang) | 6fe95fbbe4 | |
agentzh (章亦春) | 89bdbc7cca | |
agentzh (章亦春) | e1c0786358 | |
agentzh (章亦春) | 2584e135ed | |
agentzh (章亦春) | 9e49dee28a | |
agentzh (章亦春) | 5e4d755aad | |
agentzh (章亦春) | 52cf79ee28 | |
agentzh (章亦春) | 8faebfd44f | |
agentzh (章亦春) | 655bf32451 | |
Veniamin Gvozdikov | cef05fbb4b | |
agentzh (章亦春) | 85b5caf105 | |
agentzh (章亦春) | 01a7c536a3 | |
agentzh (章亦春) | 65237ea02f | |
agentzh (章亦春) | 6a805a1e28 | |
agentzh (章亦春) | 51fff05213 | |
agentzh (章亦春) | 772dc15121 | |
agentzh (章亦春) | 4a24efa64f | |
agentzh (章亦春) | c885306e32 | |
agentzh (章亦春) | dcc95a3b33 | |
agentzh (章亦春) | 4367838ae4 | |
agentzh (章亦春) | 4b236d13b0 | |
agentzh (章亦春) | b7ffa0d0e5 | |
agentzh (章亦春) | 93a68930aa | |
agentzh (章亦春) | abc99a3610 | |
agentzh (章亦春) | e5d8803af6 | |
agentzh (章亦春) | c21b63ea3f | |
agentzh (章亦春) | e17fa45a12 | |
agentzh (章亦春) | c1d79abf0e | |
agentzh (章亦春) | 0a1195e7a9 | |
agentzh (章亦春) | 0409ce05b8 | |
agentzh (章亦春) | 14167b6890 | |
agentzh (章亦春) | ecc5816593 | |
agentzh (章亦春) | 1aae4c3350 | |
agentzh (章亦春) | d5fb61765f | |
agentzh (章亦春) | fdfd34ccfd | |
agentzh (章亦春) | db1a5fce34 | |
agentzh (章亦春) | 4ae742cb70 | |
agentzh (章亦春) | 77f94345d1 | |
agentzh (章亦春) | 85b7fca736 | |
agentzh (章亦春) | 969d1d14ed | |
agentzh (章亦春) | efbc3cc213 | |
agentzh (章亦春) | 5b91b67796 | |
agentzh (章亦春) | ebed2ed1c2 | |
agentzh (章亦春) | 37bbfd4378 | |
agentzh (章亦春) | 4118c23f95 | |
agentzh (章亦春) | 2d7a4ad019 | |
agentzh (章亦春) | 28e127dd92 | |
agentzh (章亦春) | 21a9b100a1 | |
agentzh (章亦春) | 78e850f1b6 | |
agentzh (章亦春) | 3373388062 | |
agentzh (章亦春) | 1921477c18 | |
agentzh (章亦春) | 8e363e3493 | |
agentzh (章亦春) | c74b535bb2 | |
agentzh (章亦春) | e800242da6 | |
agentzh (章亦春) | 07a2a8d1c3 | |
agentzh (章亦春) | 2a871e5740 | |
agentzh (章亦春) | 139b2911ea | |
agentzh (章亦春) | 1de4bb9338 | |
agentzh (章亦春) | baefa9126e | |
agentzh (章亦春) | 2ad1408ba9 | |
agentzh (章亦春) | 82a58c989f | |
agentzh (章亦春) | 3d4784c731 | |
agentzh (章亦春) | a8a9c9577a | |
agentzh (章亦春) | 950eafe167 | |
agentzh (章亦春) | d93314a122 | |
agentzh (章亦春) | 585a62afa6 | |
agentzh (章亦春) | 03451f5037 | |
agentzh (章亦春) | bfe8fda504 | |
agentzh (章亦春) | 914c4c5ac4 | |
agentzh (章亦春) | 938d3731c8 | |
agentzh (章亦春) | 99e1bd7079 | |
agentzh (章亦春) | ba199714bc | |
agentzh (章亦春) | 281c06b2ed | |
agentzh (章亦春) | 921603b036 | |
agentzh (章亦春) | 140c431a59 | |
agentzh (章亦春) | 0a0f70f4e8 | |
agentzh (章亦春) | 21f8910725 | |
agentzh (章亦春) | 1b11b4840f | |
agentzh (章亦春) | 668c00fdb8 | |
agentzh (章亦春) | 3f8ad8af58 | |
agentzh (章亦春) | eecc5010eb | |
agentzh (章亦春) | 2ee1f58571 | |
agentzh (章亦春) | 4145db0b35 | |
agentzh (章亦春) | 88c1439437 | |
agentzh (章亦春) | e8990b7d03 | |
agentzh (章亦春) | 41d48ab573 | |
agentzh (章亦春) | ba7a3d6c44 | |
agentzh (章亦春) | 8c5f23d79a | |
agentzh (章亦春) | a3cd675f1e | |
agentzh (章亦春) | a56bd55dac | |
agentzh (章亦春) | 7c0c2cb944 | |
agentzh (章亦春) | 9b1da949a3 | |
agentzh (章亦春) | b76f452233 | |
agentzh (章亦春) | 94f1718e8d | |
agentzh (章亦春) | 8294e9b37a | |
agentzh (章亦春) | 558cbf12fc | |
agentzh (章亦春) | 8439b517f3 | |
agentzh (章亦春) | 2762f39fc4 | |
agentzh (章亦春) | 74d66c1027 | |
agentzh (章亦春) | de5e5e25de | |
agentzh (章亦春) | 479fa188f0 | |
agentzh (章亦春) | 7231e95996 | |
agentzh (章亦春) | 8b66f41ea3 | |
agentzh (章亦春) | deeea162c7 | |
agentzh (章亦春) | 06c8b65a8c | |
agentzh (章亦春) | 74c48651b9 | |
agentzh (章亦春) | ce803e8a94 | |
agentzh (章亦春) | 843fd34df6 | |
agentzh (章亦春) | 39cea1cbb3 | |
agentzh (章亦春) | b4f3bd982f | |
agentzh (章亦春) | fcb85fb288 | |
agentzh (章亦春) | 9a756394cc | |
agentzh (章亦春) | 922f49f734 | |
agentzh (章亦春) | 99c37ea419 | |
agentzh (章亦春) | 767863f552 | |
agentzh (章亦春) | 45eb5fd21d | |
agentzh (章亦春) | 926f75812b | |
agentzh (章亦春) | 0fed5de57c | |
agentzh (章亦春) | deff21617c | |
agentzh (章亦春) | 2d3383ee54 | |
agentzh (章亦春) | f2f8a02aa9 | |
agentzh (章亦春) | d10a7ece5c | |
agentzh (章亦春) | b01704d715 | |
agentzh (章亦春) | fa6683d2d0 | |
agentzh (章亦春) | 746320740a | |
agentzh (章亦春) | 627f55d5d0 | |
agentzh (章亦春) | 4579111c27 | |
agentzh (章亦春) | c9d5094560 | |
agentzh (章亦春) | de51f31cda | |
agentzh (章亦春) | a4a3c09c76 | |
agentzh (章亦春) | ec23d93c0d | |
agentzh (章亦春) | f459d71013 | |
agentzh (章亦春) | 367a5d8c5f | |
agentzh (章亦春) | dfe629a607 | |
agentzh (章亦春) | d41cb7132c | |
agentzh (章亦春) | 7c210171d1 | |
agentzh (章亦春) | 51c12f72d6 | |
agentzh (章亦春) | e95dc58c6e | |
agentzh (章亦春) | bb0af04df3 | |
agentzh (章亦春) | c528989ead | |
agentzh (章亦春) | 71a3060051 | |
agentzh (章亦春) | 3ba6ac3224 | |
agentzh (章亦春) | cc460be049 | |
agentzh (章亦春) | 134e901166 | |
agentzh (章亦春) | fda2e1e693 | |
agentzh (章亦春) | e9a14f843d | |
agentzh (章亦春) | 475d430fd6 | |
agentzh (章亦春) | ac6b83aff8 | |
agentzh (章亦春) | c93802bfed | |
agentzh (章亦春) | e67456cc26 | |
agentzh (章亦春) | 966222feef | |
agentzh (章亦春) | 67d50a58bf | |
agentzh (章亦春) | 3b79af7b99 | |
agentzh (章亦春) | 60d348d651 | |
agentzh (章亦春) | 2d2fabc6cd | |
agentzh (章亦春) | f6b914d594 | |
agentzh (章亦春) | 5ee253a0e6 | |
agentzh (章亦春) | fc78d0290f | |
agentzh (章亦春) | 9670d80bc1 | |
agentzh (章亦春) | 91fc8d50ef | |
agentzh (章亦春) | d27c62e35f | |
agentzh (章亦春) | cc574137a0 | |
agentzh (章亦春) | a6814b92ea | |
agentzh (章亦春) | 64da4f2081 | |
agentzh (章亦春) | a05b74863b | |
agentzh (章亦春) | 722e2e26c3 | |
agentzh (章亦春) | 5712e9bfdf | |
agentzh (章亦春) | f589bfc4f0 | |
Pan Fan | b76b9903de | |
agentzh (章亦春) | fb89742f47 | |
agentzh (章亦春) | 487eb2e40a | |
agentzh (章亦春) | 6e9ed6fa71 | |
agentzh (章亦春) | 9afd5ad5f7 | |
agentzh (章亦春) | bfdd9471fc | |
agentzh (章亦春) | 5ef81b5aab | |
agentzh (章亦春) | 6dd8f079dd | |
agentzh (章亦春) | 06312e656b | |
agentzh (章亦春) | 1bc8f9b8be | |
agentzh (章亦春) | 6d1405ceaa | |
agentzh (章亦春) | af701e5b64 | |
agentzh (章亦春) | 5fb3e869e5 | |
Weibin Yao | 35afee967e | |
agentzh (章亦春) | 1a91ab941c | |
agentzh (章亦春) | 2b7c8182d9 | |
agentzh (章亦春) | 6081a9b032 | |
agentzh (章亦春) | 5fd1a15da2 | |
agentzh (章亦春) | 0e98bb399f | |
agentzh (章亦春) | 041652a80d | |
agentzh (章亦春) | 74c6036eb1 | |
agentzh (章亦春) | 68fe4b0a84 | |
agentzh (章亦春) | 85a80e83b2 | |
agentzh (章亦春) | d0fc49168d | |
agentzh (章亦春) | 893262d13a | |
agentzh (章亦春) | 89d675fa91 | |
agentzh (章亦春) | 0e42b1d9ef | |
agentzh (章亦春) | 16b594b22c | |
agentzh (章亦春) | fbb918187e | |
agentzh (章亦春) | 1eb06f1ef3 | |
agentzh (章亦春) | f4745c3d28 | |
agentzh (章亦春) | 99f0e9f829 | |
agentzh (章亦春) | 96c2c3559a | |
agentzh (章亦春) | 650f75a1f9 | |
agentzh (章亦春) | c629e237b3 | |
agentzh (章亦春) | d5d36acbfc | |
agentzh (章亦春) | e4cddbf6dc | |
agentzh (章亦春) | 8b2352549c | |
agentzh (章亦春) | 69eabd6677 | |
agentzh (章亦春) | 48e6ec6682 | |
agentzh (章亦春) | 658ead207e | |
agentzh (章亦春) | 10d70ab81a | |
agentzh (章亦春) | 7215210bb4 | |
agentzh (章亦春) | 091add62d7 | |
agentzh (章亦春) | a5ac948dfe | |
agentzh (章亦春) | 099c040870 | |
agentzh (章亦春) | d33c4824f6 | |
agentzh (章亦春) | 26d1d6a05e | |
agentzh (章亦春) | 8120ad81a7 | |
agentzh (章亦春) | 88b6157313 | |
agentzh (章亦春) | 8630761254 | |
agentzh (章亦春) | 98893fe49c | |
agentzh (章亦春) | a78b404789 | |
agentzh (章亦春) | 95c11ee297 | |
agentzh (章亦春) | ce8b462f06 | |
agentzh (章亦春) | 4a54fb0814 | |
agentzh (章亦春) | 02ecfd11b5 | |
agentzh (章亦春) | d36afc91dd | |
agentzh (章亦春) | e6ce800327 | |
agentzh (章亦春) | 93f9f0762d | |
agentzh (章亦春) | 3e2b93c19d | |
agentzh (章亦春) | 1161f83de3 | |
agentzh (章亦春) | 95d24296ee | |
agentzh (章亦春) | 266f623e22 |
|
@ -0,0 +1,4 @@
|
|||
*.t linguist-language=Text
|
||||
demo/* linguist-language=Text
|
||||
clients/* linguist-language=Text
|
||||
* linguist-language=C
|
|
@ -0,0 +1,26 @@
|
|||
This place is for bug reports and development discussions only. For general questions and
|
||||
discussions, please join the openresty-en mailing list instead: https://groups.google.com/group/openresty-en.
|
||||
If you want to use Chinese, please join the openresty (Chinese) mailing list instead: https://groups.google.com/group/openresty.
|
||||
Do not use Chinese in this place.
|
||||
|
||||
Before you open a new issue, please search the internet and make sure it is not duplicate.
|
||||
|
||||
Ensure you have provided the following details while reporting a problem:
|
||||
|
||||
- [ ] The exact version of the related software, including but not limited to the OpenResty version
|
||||
(if any), the NGINX core version, the `ngx_lua` module version(via `openresty -V` or `nginx -V`),
|
||||
and your operating system version(via `uname -a`).
|
||||
- [ ] **A minimal and standalone test case** that others can easily run on their side and
|
||||
reproduce the issue you are seeing.
|
||||
- [ ] Do not simply say "something is broken" or "something does not work". Always provide
|
||||
as much details as possible. Always describe **the symptoms and your expected results**.
|
||||
|
||||
You can (temporarily) enable the nginx debugging logs to see the internal workings
|
||||
of NGINX in your nginx''s `error.log` file. See http://nginx.org/en/docs/debugging_log.html
|
||||
The same instructions apply equally well to OpenResty.
|
||||
|
||||
If you are seeing crashes, please provide the full backtrace for the crash. See
|
||||
https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/#core-dump
|
||||
for more details.
|
||||
|
||||
Thanks for your cooperation.
|
|
@ -0,0 +1,2 @@
|
|||
I hereby granted the copyright of the changes in this pull request
|
||||
to the authors of this openresty project.
|
|
@ -0,0 +1,16 @@
|
|||
# check-spelling/check-spelling configuration
|
||||
|
||||
File | Purpose | Format | Info
|
||||
-|-|-|-
|
||||
[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary)
|
||||
[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
|
||||
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
|
||||
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
|
||||
[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)
|
||||
[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
|
||||
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
|
||||
|
||||
Note: you can replace any of these files with a directory by the same name (minus the suffix)
|
||||
and then include multiple files inside that directory (with that suffix) to merge multiple files together.
|
|
@ -0,0 +1,25 @@
|
|||
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
|
||||
<details><summary>If the flagged items are false positives</summary>
|
||||
|
||||
If items relate to a ...
|
||||
* binary file (or some other file you wouldn't want to check at all).
|
||||
|
||||
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||
|
||||
File paths are Perl 5 Regular Expressions - you can [test](
|
||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
|
||||
|
||||
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
|
||||
../tree/HEAD/README.md) (on whichever branch you're using).
|
||||
|
||||
* well-formed pattern.
|
||||
|
||||
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
|
||||
try adding it to the `patterns.txt` file.
|
||||
|
||||
Patterns are Perl 5 Regular Expressions - you can [test](
|
||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
||||
|
||||
Note that patterns can't match multiline strings.
|
||||
|
||||
</details>
|
|
@ -0,0 +1,4 @@
|
|||
github
|
||||
https
|
||||
ssh
|
||||
ubuntu
|
|
@ -0,0 +1,458 @@
|
|||
# marker to ignore all code on line
|
||||
^.*/\* #no-spell-check-line \*/.*$
|
||||
# marker for ignoring a comment to the end of the line
|
||||
// #no-spell-check.*$
|
||||
|
||||
# patch hunk comments
|
||||
^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
|
||||
# git index header
|
||||
index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
|
||||
|
||||
# cid urls
|
||||
(['"])cid:.*?\g{-1}
|
||||
|
||||
# data url in parens
|
||||
\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
|
||||
# data url in quotes
|
||||
([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
|
||||
# data url
|
||||
data:[-a-zA-Z=;:/0-9+]*,\S*
|
||||
|
||||
# mailto urls
|
||||
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||
|
||||
# magnet urls
|
||||
magnet:[?=:\w]+
|
||||
|
||||
# obs:
|
||||
"obs:[^"]*"
|
||||
|
||||
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
|
||||
# In this examples content, I'm using a number of different ways to match things to show various approaches
|
||||
# asciinema
|
||||
\basciinema\.org/a/[0-9a-zA-Z]+
|
||||
|
||||
# apple
|
||||
\bdeveloper\.apple\.com/[-\w?=/]+
|
||||
# Apple music
|
||||
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
|
||||
|
||||
# appveyor api
|
||||
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
|
||||
# appveyor project
|
||||
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
|
||||
|
||||
# Amazon
|
||||
|
||||
# Amazon
|
||||
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
|
||||
# AWS S3
|
||||
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
|
||||
# AWS execute-api
|
||||
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
|
||||
# AWS ELB
|
||||
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
|
||||
# AWS SNS
|
||||
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
|
||||
|
||||
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
|
||||
# YouTube url
|
||||
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
|
||||
# YouTube music
|
||||
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
|
||||
# YouTube tag
|
||||
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
|
||||
# YouTube image
|
||||
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
|
||||
# Google Accounts
|
||||
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
|
||||
# Google Analytics
|
||||
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
|
||||
# Google APIs
|
||||
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w]+
|
||||
# Google Storage
|
||||
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
|
||||
# Google Calendar
|
||||
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
|
||||
\w+\@group\.calendar\.google\.com\b
|
||||
# Google DataStudio
|
||||
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
|
||||
# The leading `/` here is as opposed to the `\b` above
|
||||
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
|
||||
# Google Docs
|
||||
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
|
||||
# Google Drive
|
||||
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
|
||||
# Google Groups
|
||||
\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
|
||||
# Google Maps
|
||||
\bmaps\.google\.com/maps\?[\w&;=]*
|
||||
# Google themes
|
||||
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
|
||||
# Google CDN
|
||||
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
|
||||
# Goo.gl
|
||||
/goo\.gl/[a-zA-Z0-9]+
|
||||
# Google Chrome Store
|
||||
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
|
||||
# Google Books
|
||||
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
|
||||
# Google Fonts
|
||||
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
|
||||
# Google Forms
|
||||
\bforms\.gle/\w+
|
||||
# Google Scholar
|
||||
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
|
||||
# Google Colab Research Drive
|
||||
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
|
||||
|
||||
# GitHub SHAs (api)
|
||||
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
|
||||
# GitHub SHAs (markdown)
|
||||
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
|
||||
# GitHub SHAs
|
||||
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
|
||||
# GitHub wiki
|
||||
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
|
||||
# githubusercontent
|
||||
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
||||
# githubassets
|
||||
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
|
||||
# gist github
|
||||
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
|
||||
# git.io
|
||||
\bgit\.io/[0-9a-zA-Z]+
|
||||
# GitHub JSON
|
||||
"node_id": "[-a-zA-Z=;:/0-9+]*"
|
||||
# Contributor
|
||||
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
|
||||
# GHSA
|
||||
GHSA(?:-[0-9a-z]{4}){3}
|
||||
|
||||
# GitLab commit
|
||||
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
|
||||
# GitLab merge requests
|
||||
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
|
||||
# GitLab uploads
|
||||
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
|
||||
# GitLab commits
|
||||
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
|
||||
|
||||
# binanace
|
||||
accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
|
||||
|
||||
# bitbucket diff
|
||||
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
|
||||
# bitbucket repositories commits
|
||||
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||
# bitbucket commits
|
||||
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||
|
||||
# bit.ly
|
||||
\bbit\.ly/\w+
|
||||
|
||||
# bitrise
|
||||
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
|
||||
|
||||
# bootstrapcdn.com
|
||||
\bbootstrapcdn\.com/[-./\w]+
|
||||
|
||||
# cdn.cloudflare.com
|
||||
\bcdnjs\.cloudflare\.com/[./\w]+
|
||||
|
||||
# circleci
|
||||
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
|
||||
|
||||
# gitter
|
||||
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
|
||||
|
||||
# gravatar
|
||||
\bgravatar\.com/avatar/[0-9a-f]+
|
||||
|
||||
# ibm
|
||||
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
|
||||
|
||||
# imgur
|
||||
\bimgur\.com/[^.]+
|
||||
|
||||
# Internet Archive
|
||||
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
|
||||
|
||||
# discord
|
||||
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
|
||||
|
||||
# Disqus
|
||||
\bdisqus\.com/[-\w/%.()!?&=_]*
|
||||
|
||||
# medium link
|
||||
\blink\.medium\.com/[a-zA-Z0-9]+
|
||||
# medium
|
||||
\bmedium\.com/\@?[^/\s"]+/[-\w]+
|
||||
|
||||
# microsoft
|
||||
\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
|
||||
# powerbi
|
||||
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
|
||||
# vs devops
|
||||
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
|
||||
|
||||
# mvnrepository.com
|
||||
\bmvnrepository\.com/[-0-9a-z./]+
|
||||
|
||||
# now.sh
|
||||
/[0-9a-z-.]+\.now\.sh\b
|
||||
|
||||
# oracle
|
||||
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
|
||||
|
||||
# chromatic.com
|
||||
/\S+.chromatic.com\S*[")]
|
||||
|
||||
# codacy
|
||||
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
|
||||
|
||||
# compai
|
||||
\bcompai\.pub/v1/png/[0-9a-f]+
|
||||
|
||||
# mailgun api
|
||||
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
|
||||
# mailgun
|
||||
\b[0-9a-z]+.mailgun.org
|
||||
|
||||
# /message-id/
|
||||
/message-id/[-\w@./%]+
|
||||
|
||||
# Reddit
|
||||
\breddit\.com/r/[/\w_]*
|
||||
|
||||
# requestb.in
|
||||
\brequestb\.in/[0-9a-z]+
|
||||
|
||||
# sched
|
||||
\b[a-z0-9]+\.sched\.com\b
|
||||
|
||||
# Slack url
|
||||
slack://[a-zA-Z0-9?&=]+
|
||||
# Slack
|
||||
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
|
||||
# Slack edge
|
||||
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
|
||||
# Slack images
|
||||
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
|
||||
|
||||
# shields.io
|
||||
\bshields\.io/[-\w/%?=&.:+;,]*
|
||||
|
||||
# stackexchange -- https://stackexchange.com/feeds/sites
|
||||
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
|
||||
|
||||
# Sentry
|
||||
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
|
||||
|
||||
# Twitter markdown
|
||||
\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
|
||||
# Twitter hashtag
|
||||
\btwitter\.com/hashtag/[\w?_=&]*
|
||||
# Twitter status
|
||||
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
|
||||
# Twitter profile images
|
||||
\btwimg\.com/profile_images/[_\w./]*
|
||||
# Twitter media
|
||||
\btwimg\.com/media/[-_\w./?=]*
|
||||
# Twitter link shortened
|
||||
\bt\.co/\w+
|
||||
|
||||
# facebook
|
||||
\bfburl\.com/[0-9a-z_]+
|
||||
# facebook CDN
|
||||
\bfbcdn\.net/[\w/.,]*
|
||||
# facebook watch
|
||||
\bfb\.watch/[0-9A-Za-z]+
|
||||
|
||||
# dropbox
|
||||
\bdropbox\.com/s/[^/\s"]+/[-0-9A-Za-z_.%]+
|
||||
|
||||
# ipfs protocol
|
||||
ipfs://[0-9a-z]*
|
||||
# ipfs url
|
||||
/ipfs/[0-9a-z]*
|
||||
|
||||
# w3
|
||||
\bw3\.org/[-0-9a-zA-Z/#.]+
|
||||
|
||||
# loom
|
||||
\bloom\.com/embed/[0-9a-f]+
|
||||
|
||||
# regex101
|
||||
\bregex101\.com/r/[^/\s"]+/\d+
|
||||
|
||||
# figma
|
||||
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
|
||||
|
||||
# freecodecamp.org
|
||||
\bfreecodecamp\.org/[-\w/.]+
|
||||
|
||||
# image.tmdb.org
|
||||
\bimage\.tmdb\.org/[/\w.]+
|
||||
|
||||
# mermaid
|
||||
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
|
||||
|
||||
# gitweb
|
||||
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
|
||||
|
||||
# HyperKitty lists
|
||||
/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
|
||||
|
||||
# lists
|
||||
/thread\.html/[^"\s]+
|
||||
|
||||
# list-management
|
||||
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
|
||||
|
||||
# kubectl.kubernetes.io/last-applied-configuration
|
||||
"kubectl.kubernetes.io/last-applied-configuration": ".*"
|
||||
|
||||
# pgp
|
||||
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
|
||||
|
||||
# Spotify
|
||||
\bopen\.spotify\.com/embed/playlist/\w+
|
||||
|
||||
# mastodon.social
|
||||
\bmastodon\.social/(?:media/|\@)[?&=0-9a-zA-Z]*
|
||||
|
||||
# scastie
|
||||
\bscastie\.scala-lang\.org/[^/]+/\w+
|
||||
|
||||
# images.unsplash.com
|
||||
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
|
||||
|
||||
# pastebin
|
||||
\bpastebin\.com/[\w/]+
|
||||
|
||||
# ANSI color codes
|
||||
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
|
||||
|
||||
# URL escaped characters
|
||||
\%[0-9A-F][A-F]
|
||||
# IPv6
|
||||
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
|
||||
# c99 hex digits (not the full format, just one I've seen)
|
||||
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
|
||||
# Punycode
|
||||
\bxn--[-0-9a-z]+
|
||||
# sha
|
||||
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
|
||||
# sha-... -- uses a fancy capture
|
||||
(['"]|")[0-9a-f]{40,}\g{-1}
|
||||
# hex runs
|
||||
\b[0-9a-fA-F]{16,}\b
|
||||
# hex in url queries
|
||||
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
|
||||
# ssh
|
||||
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
|
||||
# PGP
|
||||
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
|
||||
# uuid:
|
||||
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||
# hex digits including css/html color classes:
|
||||
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_]*[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
|
||||
# integrity
|
||||
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
|
||||
|
||||
# https://www.gnu.org/software/groff/manual/groff.html
|
||||
# man troff content
|
||||
\\f[BCIPR]
|
||||
# '
|
||||
\\\(aq
|
||||
|
||||
# .desktop mime types
|
||||
^MimeTypes?=.*$
|
||||
# .desktop localized entries
|
||||
^[A-Z][a-z]+\[[a-z]+\]=.*$
|
||||
|
||||
# IServiceProvider
|
||||
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||
|
||||
# crypt
|
||||
"\$2[ayb]\$.{56}"
|
||||
|
||||
# Input to GitHub JSON
|
||||
content: "[-a-zA-Z=;:/0-9+]*="
|
||||
|
||||
# Python stringprefix / binaryprefix
|
||||
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
|
||||
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
|
||||
|
||||
# Regular expressions for (P|p)assword
|
||||
\([A-Z]\|[a-z]\)[a-z]+
|
||||
|
||||
# JavaScript regular expressions
|
||||
/.*/[gim]*\.test\(
|
||||
\.replace\(/[^/\s"]*/[gim]*\s*,
|
||||
|
||||
# Go regular expressions
|
||||
regexp?\.MustCompile\(`[^`]*`\)
|
||||
|
||||
# sed regular expressions
|
||||
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
|
||||
|
||||
# kubernetes pod status lists
|
||||
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
|
||||
|
||||
# kubectl - pods in CrashLoopBackOff
|
||||
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
|
||||
|
||||
# kubernetes object suffix
|
||||
-[0-9a-f]{10}-\w{5}\s
|
||||
|
||||
# posthog secrets
|
||||
posthog\.init\((['"])phc_[^"',]+\g{-1},
|
||||
|
||||
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
|
||||
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
|
||||
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
|
||||
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
|
||||
## You could manually change `(?i)X...` to use `[Xx]...`
|
||||
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
|
||||
# Lorem
|
||||
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
|
||||
|
||||
# Non-English
|
||||
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||
|
||||
# French
|
||||
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||
\b[LN]'+[a-z]+\b
|
||||
|
||||
# latex
|
||||
\\(?:n(?:ew|ormal)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
|
||||
|
||||
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
|
||||
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
|
||||
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
||||
# Note that the next example is no longer necessary if you are using
|
||||
# to match a string starting with a `#`, use a character-class:
|
||||
[#]backwards
|
||||
# version suffix <word>v#
|
||||
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||
# Compiler flags (Scala)
|
||||
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||
# Compiler flags
|
||||
(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||
# Compiler flags (linker)
|
||||
,-B
|
||||
# curl arguments
|
||||
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
|
||||
# set arguments
|
||||
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
|
||||
# tar arguments
|
||||
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
|
||||
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
|
||||
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
|
||||
# macOS temp folders
|
||||
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/
|
|
@ -0,0 +1,59 @@
|
|||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||
(?:^|/)(?i)COPYRIGHT
|
||||
(?:^|/)(?i)LICEN[CS]E
|
||||
(?:^|/)go\.sum$
|
||||
(?:^|/)package(?:-lock|)\.json$
|
||||
(?:^|/)vendor/
|
||||
ignore$
|
||||
\.a$
|
||||
\.ai$
|
||||
\.avi$
|
||||
\.bmp$
|
||||
\.bz2$
|
||||
\.crt$
|
||||
\.dll$
|
||||
\.docx?$
|
||||
\.drawio$
|
||||
\.DS_Store$
|
||||
\.eot$
|
||||
\.exe$
|
||||
\.gif$
|
||||
\.gitattributes$
|
||||
\.graffle$
|
||||
\.gz$
|
||||
\.html$
|
||||
\.icns$
|
||||
\.ico$
|
||||
\.jar$
|
||||
\.jks$
|
||||
\.jpe?g$
|
||||
\.js$
|
||||
\.key$
|
||||
\.lib$
|
||||
\.lock$
|
||||
\.map$
|
||||
\.min\..
|
||||
\.mod$
|
||||
\.mp[34]$
|
||||
\.nav$
|
||||
\.o$
|
||||
\.ocf$
|
||||
\.otf$
|
||||
\.pdf$
|
||||
\.pem$
|
||||
\.png$
|
||||
\.styl$
|
||||
\.psd$
|
||||
\.s$
|
||||
\.svg$
|
||||
\.tar$
|
||||
\.tiff?$
|
||||
\.ttf$
|
||||
\.uve$
|
||||
\.wav$
|
||||
\.webm$
|
||||
\.webp$
|
||||
\.woff2?$
|
||||
\.zip$
|
||||
^\.github/
|
||||
^\Q.github/workflows/spelling.yml\E$
|
|
@ -0,0 +1,51 @@
|
|||
agentzh
|
||||
COMPAT
|
||||
csv
|
||||
dav
|
||||
dll
|
||||
DLUAJIT
|
||||
exe
|
||||
flv
|
||||
gcc
|
||||
gmail
|
||||
gunzip
|
||||
gzip
|
||||
html
|
||||
http
|
||||
imagename
|
||||
imap
|
||||
IOCP
|
||||
ipv
|
||||
jit
|
||||
json
|
||||
Linux
|
||||
lua
|
||||
luajit
|
||||
Microsoft
|
||||
mkdir
|
||||
MSYS
|
||||
nginx
|
||||
ngx
|
||||
NUMMODE
|
||||
objs
|
||||
openresty
|
||||
openssl
|
||||
pcre
|
||||
perl
|
||||
pid
|
||||
preread
|
||||
rds
|
||||
README
|
||||
realip
|
||||
sbin
|
||||
SETSIZE
|
||||
smtp
|
||||
ssl
|
||||
tarballs
|
||||
taskkill
|
||||
tasklist
|
||||
todo
|
||||
toolchain
|
||||
xcflags
|
||||
Yichun
|
||||
zlib
|
|
@ -0,0 +1,56 @@
|
|||
# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
|
||||
# \bm_data\b
|
||||
|
||||
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
|
||||
# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
|
||||
# to use this:
|
||||
#\bfit\(
|
||||
|
||||
# s.b. GitHub
|
||||
\bGithub\b
|
||||
|
||||
# s.b. GitLab
|
||||
\bGitlab\b
|
||||
|
||||
# s.b. JavaScript
|
||||
\bJavascript\b
|
||||
|
||||
# s.b. Microsoft
|
||||
\bMicroSoft\b
|
||||
|
||||
# s.b. another
|
||||
\ban[- ]other\b
|
||||
|
||||
# s.b. greater than
|
||||
\bgreater then\b
|
||||
|
||||
# s.b. into
|
||||
\bin to\b
|
||||
|
||||
# s.b. less than
|
||||
\bless then\b
|
||||
|
||||
# s.b. otherwise
|
||||
\bother[- ]wise\b
|
||||
|
||||
# s.b. nonexistent
|
||||
\bnon existing\b
|
||||
\b[Nn]o[nt][- ]existent\b
|
||||
|
||||
# s.b. preexisting
|
||||
[Pp]re-existing
|
||||
|
||||
# s.b. preempt
|
||||
[Pp]re-empt\b
|
||||
|
||||
# s.b. preemptively
|
||||
[Pp]re-emptively
|
||||
|
||||
# s.b. reentrancy
|
||||
[Rr]e-entrancy
|
||||
|
||||
# s.b. reentrant
|
||||
[Rr]e-entrant
|
||||
|
||||
# Reject duplicate words
|
||||
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s
|
|
@ -0,0 +1,2 @@
|
|||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||
\.md$
|
|
@ -0,0 +1,18 @@
|
|||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||
|
||||
# acceptable duplicates
|
||||
# ls directory listings
|
||||
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
|
||||
# C types
|
||||
\s(long|LONG) \g{-1}\s
|
||||
# javadoc / .net
|
||||
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
|
||||
|
||||
# Commit message -- Signed-off-by and friends
|
||||
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
|
||||
|
||||
# Autogenerated revert commit message
|
||||
^This reverts commit [0-9a-f]{40}\.$
|
||||
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
|
@ -0,0 +1,10 @@
|
|||
^attache$
|
||||
benefitting
|
||||
occurences?
|
||||
^dependan.*
|
||||
^oer$
|
||||
Sorce
|
||||
^[Ss]pae.*
|
||||
^untill$
|
||||
^untilling$
|
||||
^wether.*
|
|
@ -0,0 +1,18 @@
|
|||
name: Linting on markdown files
|
||||
on:
|
||||
pull_request_target:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
lint-content:
|
||||
name: Lint content markdown files
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Lint markdown files
|
||||
uses: avto-dev/markdown-lint@v1
|
||||
with:
|
||||
config: './.markdownlint.jsonc'
|
||||
args: './content/**/*.md'
|
|
@ -0,0 +1,30 @@
|
|||
name: "Lint PR"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
# Configure which types are allowed.
|
||||
# Default: https://github.com/commitizen/conventional-commit-types
|
||||
types: |
|
||||
bugfix # bug fixes
|
||||
change # backward incompatible changes
|
||||
doc # documentation changes including code comments
|
||||
editor # code editor related configurations
|
||||
feature # implementing a new feature
|
||||
optimize # performance optimizations
|
||||
refactor # code refactoring and other code rearrangement
|
||||
style # coding style changes
|
||||
tests # test suite changes
|
|
@ -0,0 +1,96 @@
|
|||
name: Spell checking
|
||||
|
||||
# Updating pull request branches is managed via comment handling.
|
||||
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
|
||||
#
|
||||
# These elements work together to make it happen:
|
||||
#
|
||||
# `on.issue_comment`
|
||||
# This event listens to comments by users asking to update the metadata.
|
||||
#
|
||||
# `jobs.update`
|
||||
# This job runs in response to an issue_comment and will push a new commit
|
||||
# to update the spelling metadata.
|
||||
#
|
||||
# `with.experimental_apply_changes_via_bot`
|
||||
# Tells the action to support and generate messages that enable it
|
||||
# to make a commit to update the spelling metadata.
|
||||
#
|
||||
# `with.ssh_key`
|
||||
# In order to trigger workflows when the commit is made, you can provide a
|
||||
# secret (typically, a write-enabled github deploy key).
|
||||
#
|
||||
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
tags-ignore: ["**"]
|
||||
pull_request_target:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
name: Spell checking
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
actions: read
|
||||
outputs:
|
||||
followup: ${{ steps.spelling.outputs.followup }}
|
||||
runs-on: ubuntu-latest
|
||||
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
|
||||
concurrency:
|
||||
group: spelling-${{ github.event.pull_request.number || github.ref }}
|
||||
# note: If you use only_check_changed_files, you do not want cancel-in-progress
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@main
|
||||
with:
|
||||
suppress_push_for_open_pull_request: 1
|
||||
checkout: true
|
||||
post_comment: 0
|
||||
experimental_apply_changes_via_bot: 1
|
||||
extra_dictionaries:
|
||||
cspell:filetypes/filetypes.txt
|
||||
|
||||
comment:
|
||||
name: Report
|
||||
runs-on: ubuntu-latest
|
||||
needs: spelling
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@main
|
||||
with:
|
||||
checkout: true
|
||||
task: ${{ needs.spelling.outputs.followup }}
|
||||
experimental_apply_changes_via_bot: 1
|
||||
|
||||
update:
|
||||
name: Update PR
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{
|
||||
github.event_name == 'issue_comment' &&
|
||||
github.event.issue.pull_request &&
|
||||
contains(github.event.comment.body, '@check-spelling-bot apply')
|
||||
}}
|
||||
concurrency:
|
||||
group: spelling-update-${{ github.event.issue.number }}
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: apply spelling updates
|
||||
uses: check-spelling/check-spelling@main
|
||||
with:
|
||||
experimental_apply_changes_via_bot: 1
|
||||
checkout: true
|
||||
ssh_key: "${{ secrets.CHECK_SPELLING }}"
|
|
@ -2,6 +2,7 @@
|
|||
bin/openresty.fcgi
|
||||
demo/Admin/.rsync
|
||||
*~
|
||||
*.swo
|
||||
*.json
|
||||
*.o
|
||||
*.hi
|
||||
|
@ -65,7 +66,13 @@ util/blog-rows.sql
|
|||
util/comments.sql
|
||||
util/posts.sql
|
||||
ngx_openresty-*
|
||||
openresty-*
|
||||
work/
|
||||
reindex
|
||||
t/*.t_
|
||||
upload
|
||||
upload-win32
|
||||
html_out/
|
||||
TODO
|
||||
doc/LuaJIT-2.1/changes.pod
|
||||
t/servroot
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
dist: bionic
|
||||
|
||||
branches:
|
||||
only:
|
||||
- "master"
|
||||
|
||||
os: linux
|
||||
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- axel
|
||||
- dos2unix
|
||||
- libgd-dev
|
||||
|
||||
_linux-s390x: &linux-s390x
|
||||
os: linux
|
||||
arch: s390x
|
||||
dist: bionic
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- axel
|
||||
- dos2unix
|
||||
- libgd-dev
|
||||
- libpcre3
|
||||
- libpcre3-dev
|
||||
- mercurial
|
||||
- libpq-dev
|
||||
before_install:
|
||||
- sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||
install:
|
||||
- cpanm --sudo --notest Test::Nginx IPC::Run3 > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
|
||||
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
|
||||
- cd openssl-$OPENSSL_VER/
|
||||
- patch -p1 < ../patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch
|
||||
- ./config no-threads shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- sudo ln -s /usr/bin/make /usr/bin/gmake
|
||||
script:
|
||||
- util/mirror-tarballs > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd "openresty-$(./util/ver)"
|
||||
- ./configure $ENABLE_HTTP3_OPTION --prefix=$OPENRESTY_PREFIX --with-cc-opt="-I$PCRE_INC -I$OPENSSL_INC" --with-ld-opt="-L$PCRE_LIB -L$OPENSSL_LIB -Wl,-rpath,$PCRE_LIB:$OPENSSL_LIB" --with-pcre-jit --with-http_ssl_module --with-debug -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make install > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- export PATH=$OPENRESTY_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$PATH
|
||||
- nginx -V
|
||||
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
|
||||
- prove -I. -r t/
|
||||
|
||||
_linux-ppc64le: &linux-ppc64le
|
||||
os: linux
|
||||
arch: ppc64le
|
||||
dist: bionic
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- axel
|
||||
- dos2unix
|
||||
- libgd-dev
|
||||
- libpcre3
|
||||
- libpcre3-dev
|
||||
- mercurial
|
||||
- libpq-dev
|
||||
install:
|
||||
- cpanm --sudo --notest Test::Nginx IPC::Run3 > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
|
||||
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
|
||||
- cd openssl-$OPENSSL_VER/
|
||||
- patch -p1 < ../patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch
|
||||
- ./config no-threads shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- sudo ln -s /usr/bin/make /usr/bin/gmake
|
||||
script:
|
||||
- util/mirror-tarballs > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd "openresty-$(./util/ver)"
|
||||
- ./configure $ENABLE_HTTP3_OPTION --prefix=$OPENRESTY_PREFIX --with-cc-opt="-I$PCRE_INC -I$OPENSSL_INC" --with-ld-opt="-L$PCRE_LIB -L$OPENSSL_LIB -Wl,-rpath,$PCRE_LIB:$OPENSSL_LIB" --with-pcre-jit --with-http_ssl_module --with-debug -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make install > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- export PATH=$OPENRESTY_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$PATH
|
||||
- nginx -V
|
||||
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- download-cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- JOBS=3
|
||||
- PCRE_VER=8.44
|
||||
- PCRE_PREFIX=/opt/pcre
|
||||
- PCRE_LIB=$PCRE_PREFIX/lib
|
||||
- PCRE_INC=$PCRE_PREFIX/include
|
||||
- OPENSSL_PREFIX=/opt/ssl
|
||||
- OPENSSL_LIB=$OPENSSL_PREFIX/lib
|
||||
- OPENSSL_INC=$OPENSSL_PREFIX/include
|
||||
- OPENRESTY_PREFIX=/opt/openresty
|
||||
jobs:
|
||||
- OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f ENABLE_HTTP3_OPTION=--with-http_v3_module
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- <<: *linux-s390x
|
||||
env: OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f ENABLE_HTTP3_OPTION=--with-http_v3_module
|
||||
- <<: *linux-ppc64le
|
||||
env: OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f ENABLE_HTTP3_OPTION=--with-http_v3_module
|
||||
|
||||
install:
|
||||
- cpanm --sudo --notest Test::Nginx IPC::Run3 > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi
|
||||
- if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
|
||||
- tar zxf download-cache/pcre-$PCRE_VER.tar.gz
|
||||
- cd pcre-$PCRE_VER/
|
||||
- ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
|
||||
- cd openssl-$OPENSSL_VER/
|
||||
- patch -p1 < ../patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch
|
||||
- ./config no-threads shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- sudo ln -s /usr/bin/make /usr/bin/gmake
|
||||
|
||||
script:
|
||||
- util/mirror-tarballs > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd "openresty-$(./util/ver)"
|
||||
- ./configure $ENABLE_HTTP3_OPTION --prefix=$OPENRESTY_PREFIX --with-cc-opt="-I$PCRE_INC -I$OPENSSL_INC" --with-ld-opt="-L$PCRE_LIB -L$OPENSSL_LIB -Wl,-rpath,$PCRE_LIB:$OPENSSL_LIB" --with-pcre-jit --with-http_ssl_module --with-debug -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- sudo make install > build.log 2>&1 || (cat build.log && exit 1)
|
||||
- cd ..
|
||||
- export PATH=$OPENRESTY_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$PATH
|
||||
- nginx -V
|
||||
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
|
||||
- prove -I. -r t/
|
|
@ -0,0 +1,514 @@
|
|||
Copyright (C) 2009-2015, by Yichun "agentzh" Zhang, OpenResty Inc.
|
||||
|
||||
Copyright (C) 2009-2014, by Xiaozhe Wang (chaoslawful) <chaoslawful@gmail.
|
||||
com>.
|
||||
|
||||
Copyright (C) 2010-2014, by FRiCKLE Piotr Sikora <info@frickle.com>.
|
||||
|
||||
Copyright (C) 2015, by Shuxin Yang.
|
||||
|
||||
Copyright (c) 2010, 2011, Jiale "calio" Zhi <vipcalio@gmail.com>.
|
||||
|
||||
Copyright (C) Guanlan Dai
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Copyright (c) 2010, Marcus Clyne, Simpl (simpl.it)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the organization (Simpl) nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL MARCUS CLYNE OR SIMPL BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2002-2015 Igor Sysoev
|
||||
Copyright (C) 2011-2015 Nginx, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
NGINX License
|
||||
|
||||
Copyright (C) 2002-2009 Igor Sysoev
|
||||
Copyright (C) 2009-2013 Sergey A. Osokin
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
|
||||
Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN
|
||||
THE SOFTWARE.
|
||||
|
||||
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Lua License
|
||||
|
||||
Copyright (C) 1994-2012 Lua.org, PUC-Rio.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN
|
||||
THE SOFTWARE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Lua-cjson License
|
||||
|
||||
Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
SHA-1 implementation in NDK
|
||||
|
||||
Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
All rights reserved.
|
||||
|
||||
This package is an SSL implementation written
|
||||
by Eric Young (eay@cryptsoft.com).
|
||||
The implementation was written so as to conform with Netscapes SSL.
|
||||
|
||||
This library is free for commercial and non-commercial use as long as
|
||||
the following conditions are aheared to. The following conditions
|
||||
apply to all code found in this distribution, be it the RC4, RSA,
|
||||
lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
included with this distribution is covered by the same copyright terms
|
||||
except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
|
||||
Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
the code are not to be removed.
|
||||
If this package is used in a product, Eric Young should be given attribution
|
||||
as the author of the parts of the library used.
|
||||
This can be in the form of a textual message at program startup or
|
||||
in documentation (online or textual) provided with the package.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
"This product includes cryptographic software written by
|
||||
Eric Young (eay@cryptsoft.com)"
|
||||
The word 'cryptographic' can be left out if the rouines from the library
|
||||
being used are not cryptographic related :-).
|
||||
4. If you include any Windows specific code (or a derivative thereof) from
|
||||
the apps directory (application code) you must include an acknowledgement:
|
||||
"This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
The licence and distribution terms for any publically available version
|
||||
or
|
||||
derivative of this code cannot be changed. i.e. this code cannot simply
|
||||
be
|
||||
copied and put under another distribution licence
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
OpenSSL
|
||||
|
||||
Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software developed by the OpenSSL Project
|
||||
for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
|
||||
4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
endorse or promote products derived from this software without
|
||||
prior written permission. For written permission, please contact
|
||||
openssl-core@openssl.org.
|
||||
|
||||
5. Products derived from this software may not be called "OpenSSL"
|
||||
nor may "OpenSSL" appear in their names without prior written
|
||||
permission of the OpenSSL Project.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes software developed by the OpenSSL Project
|
||||
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This product includes cryptographic software written by Eric Young
|
||||
(eay@cryptsoft.com). This product includes software written by Tim
|
||||
Hudson (tjh@cryptsoft.com).
|
||||
|
||||
Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
All rights reserved.
|
||||
|
||||
This package is an SSL implementation written
|
||||
by Eric Young (eay@cryptsoft.com).
|
||||
The implementation was written so as to conform with Netscapes SSL.
|
||||
|
||||
This library is free for commercial and non-commercial use as long as
|
||||
the following conditions are aheared to. The following conditions
|
||||
apply to all code found in this distribution, be it the RC4, RSA,
|
||||
lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
included with this distribution is covered by the same copyright terms
|
||||
except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
|
||||
Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
the code are not to be removed.
|
||||
If this package is used in a product, Eric Young should be given attribution
|
||||
as the author of the parts of the library used.
|
||||
This can be in the form of a textual message at program startup or
|
||||
in documentation (online or textual) provided with the package.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
"This product includes cryptographic software written by
|
||||
Eric Young (eay@cryptsoft.com)"
|
||||
The word 'cryptographic' can be left out if the rouines from the library
|
||||
being used are not cryptographic related :-).
|
||||
|
||||
4. If you include any Windows specific code (or a derivative thereof) from
|
||||
the apps directory (application code) you must include an acknowledgement:
|
||||
"This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
The licence and distribution terms for any publically available version or
|
||||
derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
copied and put under another distribution licence
|
||||
[including the GNU Public Licence.]
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
PCRE LICENCE
|
||||
------------
|
||||
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
|
||||
specified below. The documentation for PCRE, supplied in the "doc"
|
||||
directory, is distributed under the same terms as the software itself. The data
|
||||
in the testdata directory is not copyrighted and is in the public domain.
|
||||
|
||||
The basic library functions are written in C and are freestanding. Also
|
||||
included in the distribution is a set of C++ wrapper functions, and a
|
||||
just-in-time compiler that can be used to optimize pattern matching. These
|
||||
are both optional features that can be omitted when the library is built.
|
||||
|
||||
|
||||
THE BASIC LIBRARY FUNCTIONS
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2017 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
PCRE JUST-IN-TIME COMPILATION SUPPORT
|
||||
-------------------------------------
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2017 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
STACK-LESS JUST-IN-TIME COMPILER
|
||||
--------------------------------
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2017 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
THE C++ WRAPPER FUNCTIONS
|
||||
-------------------------
|
||||
|
||||
Contributed by: Google Inc.
|
||||
|
||||
Copyright (c) 2007-2012, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
|
||||
THE "BSD" LICENCE
|
||||
-----------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the name of Google
|
||||
Inc. nor the names of their contributors may be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
zlib
|
||||
|
||||
(C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
If you use the zlib library in a product, we would appreciate *not* receiving
|
||||
lengthy legal documents to sign. The sources are provided for free but without
|
||||
warranty of any kind. The library has been entirely written by Jean-loup
|
||||
Gailly and Mark Adler; it does not include third-party code.
|
||||
|
||||
If you redistribute modified sources, we would appreciate that you include in
|
||||
the file ChangeLog history information documenting your changes. Please read
|
||||
the FAQ for more information on the distribution of modified source versions.
|
|
@ -0,0 +1,233 @@
|
|||
# New ports collection makefile for: openresty
|
||||
# Date created: 2012-08-07
|
||||
# Whom: Gvozdikov Veniamin <g.veniamin@googlemail.com>
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
PORTNAME= openresty
|
||||
PORTVERSION= 1.2.1.11
|
||||
CATEGORIES= www
|
||||
MASTER_SITES= http://agentzh.org/misc/nginx/
|
||||
DISTNAME= ngx_${PORTNAME}-${PORTVERSION}
|
||||
|
||||
MAINTAINER= g.veniamin@googlemail.com
|
||||
COMMENT= OpenResty a powerful web app server by extending nginx
|
||||
|
||||
LICENSE= BSD
|
||||
|
||||
LIB_DEPENDS= pcre:${PORTSDIR}/devel/pcre
|
||||
|
||||
HAS_CONFIGURE= yes
|
||||
USE_GMAKE= yes
|
||||
USE_PERL5= yes
|
||||
|
||||
CONFIGURE_ARGS= --prefix=${PREFIX}\
|
||||
--with-cc-opt="-I ${LOCALBASE}/include" \
|
||||
--with-ld-opt="-L ${LOCALBASE}/lib" \
|
||||
--user=${WWWOWN} --group=${WWWGRP}
|
||||
|
||||
OPTIONS_DEFINE= LUACJSON LUAREDISPARS LUARDS LUARESTYDNS LUARESTYMEM \
|
||||
LUARESTYREDIS LUARESTYMYSQL LUARESTYUPLOAD LUARESTYSTRING \
|
||||
ECHO XSS COOLKIT MISC ENCSESSION HEADERSMORE SRCACHE \
|
||||
ARRAYVAR MEMC REDIS REDIS2 AUTHREQ RDSJSON RDSCVS \
|
||||
ICONV NDK DRIZZLE POSTGRES
|
||||
OPTIONS_SINGLE= GLUA
|
||||
OPTIONS_SINGLE_GLUA= LUA LUAJIT DLUA
|
||||
|
||||
LUACJSON_DESC= Lua cjson library
|
||||
LUAREDISPARS_DESC= Lua redis parser library
|
||||
LUARDS_DESC= Lua rds library
|
||||
LUARESTYDNS_DESC= Lua resty dns library
|
||||
LUARESTYMEM_DESC= Lua resty memcached library
|
||||
LUARESTYREDIS_DESC= Lua resty redis library
|
||||
LUARESTYMYSQL_DESC= Lua resty mysql library
|
||||
LUARESTYUPLOAD_DESC= Lua resty upload library
|
||||
LUARESTYSTRING_DESC= Lua resty string library
|
||||
|
||||
ECHO_DESC= Brings echo/sleep/time and more shell-style
|
||||
XSS_DESC= Native cross-site scripting support in nginx
|
||||
COOLKIT_DESC= Collection of small and useful nginx add-ons
|
||||
MISC_DESC= Various set_xxx directives added
|
||||
ENCSESSION_DESC= Encrypt and decrypt nginx variable values
|
||||
HEADERSMORE_DESC= Set and clear input and output headers
|
||||
SRCACHE_DESC= Transparent subrequest-based caching layout
|
||||
ARRAYVAR_DESC= Add support for array variables to config
|
||||
MEMC_DESC= An extended memcached module
|
||||
REDIS_DESC= HTTP redis module
|
||||
REDIS2_DESC= Module for the Redis 2.0 protocol
|
||||
AUTHREQ_DESC= Auth request module
|
||||
RDSJSON_DESC= An output filter that formats Resty
|
||||
RDSCVS_DESC= Output filter module to convert CVS
|
||||
NDK_DESC= Nginx Development Kit
|
||||
ICONV_DESC= Iconv support
|
||||
DRIZZLE_DESC= Module for talking to MySQL and Drizzle
|
||||
POSTGRES_DESC= Module for talking to Postgeres
|
||||
|
||||
DLUA_DESC= Disable Lua
|
||||
LUA_DESC= Use LUA 5.1
|
||||
LUAJIT_DESC= Use LuaJIT 2.0
|
||||
|
||||
OPTIONS_DEFAULT= MISC XSS ECHO COOLKIT ENCSESSION HEADERMORE LUA \
|
||||
SRCACHE ARRAYVAR MEMC REDIS REDIS2 AUTHREQ RDSJSON \
|
||||
RDSCVS NDK ICONV PORTGRES
|
||||
|
||||
.include <bsd.port.options.mk>
|
||||
|
||||
.if empty(${PORT_OPTIONS:MAUTHREQ})
|
||||
CONFIGURE_ARGS+= --without-http_auth_request_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MRDSJSON})
|
||||
CONFIGURE_ARGS+= --without-http_rds_json_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MRDSCVS})
|
||||
CONFIGURE_ARGS+= --without-http_rds_csv_module
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MICONV}
|
||||
CONFIGURE_ARGS+= --with-http_iconv_module
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MNDK}
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-ngx_devel_kit_module
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MDRIZZLE}
|
||||
CONFIGURE_ARGS+= --with-http_drizzle_module \
|
||||
--with-libdrizzle=${LOCALBASE}
|
||||
LIB_DEPENDS+= drizzle:${PORTSDIR}/databases/libdrizzle
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MPOSTGRES}
|
||||
CONFIGURE_ARGS+= --with-http_postgres_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MREDIS})
|
||||
CONFIGURE_ARGS+= --without-http_redis_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MREDIS2})
|
||||
CONFIGURE_ARGS+= --without-http_redis2_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MMEMC})
|
||||
CONFIGURE_ARGS+= --without-http_memc_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MARRAYVAR})
|
||||
CONFIGURE_ARGS+= --without-http_array_var_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MSRCACHE})
|
||||
CONFIGURE_ARGS+= --without-http_srcache_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MENCSESSION})
|
||||
CONFIGURE_ARGS+= --without-http_encrypted_session_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MHEADERSMORE})
|
||||
CONFIGURE_ARGS+= --without-http_headers_more_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MMISC})
|
||||
CONFIGURE_ARGS+= --without-http_set_misc_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MXSS})
|
||||
CONFIGURE_ARGS+= --without-http_xss_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MCOOLKIT})
|
||||
CONFIGURE_ARGS+= --without-http_coolkit_module
|
||||
.endif
|
||||
|
||||
.if empty(${PORT_OPTIONS:MECHO})
|
||||
CONFIGURE_ARGS+= --without-http_echo_module
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUAJIT}
|
||||
CONFIGURE_ARGS+= --with-luajit
|
||||
PLIST_SUB+= LUAJIT=""
|
||||
.else
|
||||
PLIST_SUB+= LUAJIT="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUA}
|
||||
PLIST_SUB+= LUA=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua51
|
||||
PLIST_SUB+= LUA="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MDLUA}
|
||||
CONFIGURE_ARGS+= --without-http_lua_module
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUACJSON}
|
||||
PLIST_SUB+= LUACJSON=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_cjson
|
||||
PLIST_SUB+= LUACJSON="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUAREDISPARS}
|
||||
PLIST_SUB+= LUAREDISPARS=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_redis_parser
|
||||
PLIST_SUB+= LUAREDISPARS="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARDS}
|
||||
PLIST_SUB+= LUARDS=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_rds_parser
|
||||
PLIST_SUB+= LUARDS="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYDNS}
|
||||
PLIST_SUB+= LUARESTYDNS=""
|
||||
.else
|
||||
PLIST_SUB+= LUARESTYDNS="@comment "
|
||||
CONFIGURE_ARGS+= --without-lua_resty_dns
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYMEM}
|
||||
PLIST_SUB+= LUARESTYMEM=""
|
||||
.else
|
||||
PLIST_SUB+= LUARESTYMEM="@comment "
|
||||
CONFIGURE_ARGS+= --without-lua_resty_memcached
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYREDIS}
|
||||
PLIST_SUB+= LUARESTYREDIS=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_resty_redis
|
||||
PLIST_SUB+= LUARESTYREDIS="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYMYSQL}
|
||||
PLIST_SUB+= LUARESTYMYSQL=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_resty_mysql
|
||||
PLIST_SUB+= LUARESTYMYSQL="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYUPLOAD}
|
||||
PLIST_SUB+= LUARESTYUPLOAD=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_resty_upload
|
||||
PLIST_SUB+= LUARESTYUPLOAD="@comment "
|
||||
.endif
|
||||
|
||||
.if ${PORT_OPTIONS:MLUARESTYSTRING}
|
||||
PLIST_SUB+= LUARESTYSTRING=""
|
||||
.else
|
||||
CONFIGURE_ARGS+= --without-lua_resty_string
|
||||
PLIST_SUB+= LUARESTYSTRING="@comment "
|
||||
.endif
|
||||
|
||||
.include <bsd.port.mk>
|
|
@ -0,0 +1,2 @@
|
|||
SHA256 (ngx_openresty-1.2.1.11.tar.gz) = 212c3ba07d94b17fcbd4d60054bd8457fa18de3264381e8449074c78aa05f9f5
|
||||
SIZE (ngx_openresty-1.2.1.11.tar.gz) = 2950664
|
|
@ -0,0 +1,36 @@
|
|||
--- bundle/LuaJIT-2.0.0-beta10/Makefile.orig 2012-05-09 20:00:00.000000000 +0400
|
||||
+++ bundle/LuaJIT-2.0.0-beta10/Makefile 2012-08-07 23:26:28.853477336 +0400
|
||||
@@ -38,8 +38,6 @@
|
||||
INSTALL_JITLIB= $(INSTALL_SHARE)/luajit-$(VERSION)/jit
|
||||
INSTALL_LMOD= $(INSTALL_SHARE)/lua/$(ABIVER)
|
||||
INSTALL_CMOD= $(INSTALL_LIB)/lua/$(ABIVER)
|
||||
-INSTALL_MAN= $(INSTALL_SHARE)/man/man1
|
||||
-INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
|
||||
|
||||
INSTALL_TNAME= luajit-$(VERSION)
|
||||
INSTALL_TSYMNAME= luajit
|
||||
@@ -59,7 +57,7 @@
|
||||
INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
|
||||
INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
|
||||
|
||||
-INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
|
||||
+INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) \
|
||||
$(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
|
||||
|
||||
RM= rm -f
|
||||
@@ -73,7 +71,6 @@
|
||||
FILE_T= luajit
|
||||
FILE_A= libluajit.a
|
||||
FILE_SO= libluajit.so
|
||||
-FILE_MAN= luajit.1
|
||||
FILE_PC= luajit.pc
|
||||
FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
|
||||
FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua dis_arm.lua \
|
||||
@@ -108,7 +105,6 @@
|
||||
$(LDCONFIG) $(INSTALL_LIB) && \
|
||||
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
|
||||
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
|
||||
- cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
|
||||
cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
|
||||
$(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
|
||||
$(RM) $(FILE_PC).tmp
|
|
@ -0,0 +1,47 @@
|
|||
--- bundle/lua-5.1.5/Makefile.orig 2012-08-07 14:56:49.606517458 +0400
|
||||
+++ bundle/lua-5.1.5/Makefile 2012-08-07 14:57:31.325545994 +0400
|
||||
@@ -13,7 +13,6 @@
|
||||
INSTALL_BIN= $(INSTALL_TOP)/bin
|
||||
INSTALL_INC= $(INSTALL_TOP)/include
|
||||
INSTALL_LIB= $(INSTALL_TOP)/lib
|
||||
-INSTALL_MAN= $(INSTALL_TOP)/man/man1
|
||||
#
|
||||
# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with
|
||||
# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc).
|
||||
@@ -44,7 +43,6 @@
|
||||
TO_BIN= lua luac
|
||||
TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp
|
||||
TO_LIB= liblua.a
|
||||
-TO_MAN= lua.1 luac.1
|
||||
|
||||
# Lua version and release.
|
||||
V= 5.1
|
||||
@@ -59,11 +57,10 @@
|
||||
src/lua test/hello.lua
|
||||
|
||||
install: dummy
|
||||
- cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
|
||||
+ cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
|
||||
cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
|
||||
cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
|
||||
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
|
||||
- cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
|
||||
|
||||
ranlib:
|
||||
cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB)
|
||||
@@ -95,7 +92,6 @@
|
||||
@echo "INSTALL_BIN = $(INSTALL_BIN)"
|
||||
@echo "INSTALL_INC = $(INSTALL_INC)"
|
||||
@echo "INSTALL_LIB = $(INSTALL_LIB)"
|
||||
- @echo "INSTALL_MAN = $(INSTALL_MAN)"
|
||||
@echo "INSTALL_LMOD = $(INSTALL_LMOD)"
|
||||
@echo "INSTALL_CMOD = $(INSTALL_CMOD)"
|
||||
@echo "INSTALL_EXEC = $(INSTALL_EXEC)"
|
||||
@@ -111,7 +107,6 @@
|
||||
@echo "TO_BIN = $(TO_BIN)"
|
||||
@echo "TO_INC = $(TO_INC)"
|
||||
@echo "TO_LIB = $(TO_LIB)"
|
||||
- @echo "TO_MAN = $(TO_MAN)"
|
||||
|
||||
# echo config parameters as Lua code
|
||||
# uncomment the last sed expression if you want nil instead of empty strings
|
|
@ -0,0 +1,12 @@
|
|||
--- configure.orig 2012-08-08 11:10:58.575960219 +0400
|
||||
+++ configure 2012-08-08 11:11:38.950486311 +0400
|
||||
@@ -157,6 +157,9 @@
|
||||
} elsif ($opt eq '--without-lua_redis_parser') {
|
||||
$resty_opts{no_lua_redis_parser} = 1;
|
||||
|
||||
+ } elsif ($opt eq '--without-lua_resty_dns') {
|
||||
+ $resty_opts{no_lua_resty_dns} = 1;
|
||||
+
|
||||
} elsif ($opt eq '--without-lua_resty_memcached') {
|
||||
$resty_opts{no_lua_resty_memcached} = 1;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
ngx_openresty is a full-fledged web application server by bundling
|
||||
the standard nginx core, lots of 3rd-party nginx modules, as well
|
||||
as most of their external dependencies.
|
||||
|
||||
|
||||
WWW: http://openresty.org
|
|
@ -0,0 +1,95 @@
|
|||
%%LUA%%lua/bin/luac
|
||||
%%LUA%%lua/bin/lua
|
||||
%%LUA%%lua/lib/liblua.a
|
||||
%%LUA%%lua/include/luaconf.h
|
||||
%%LUA%%lua/include/lauxlib.h
|
||||
%%LUA%%lua/include/lua.h
|
||||
%%LUA%%lua/include/lua.hpp
|
||||
%%LUA%%lua/include/lualib.h
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/luaconf.h
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/lua.hpp
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/lualib.h
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/luajit.h
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/lauxlib.h
|
||||
%%LUAJIT%%luajit/include/luajit-2.0/lua.h
|
||||
%%LUAJIT%%luajit/lib/libluajit-5.1.a
|
||||
%%LUAJIT%%luajit/lib/libluajit-5.1.so.2.0.0
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dump.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_mipsel.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/bc.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_mips.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_x64.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/v.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_ppc.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_arm.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/vmdef.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/dis_x86.lua
|
||||
%%LUAJIT%%luajit/share/luajit-2.0.0-beta10/jit/bcsave.lua
|
||||
%%LUAJIT%%luajit/bin/luajit-2.0.0-beta10
|
||||
nginx/html/index.html
|
||||
nginx/html/50x.html
|
||||
nginx/conf/koi-win
|
||||
nginx/conf/koi-utf
|
||||
nginx/conf/fastcgi_params
|
||||
nginx/conf/nginx.conf.default
|
||||
nginx/conf/fastcgi.conf
|
||||
nginx/conf/win-utf
|
||||
nginx/conf/fastcgi.conf.default
|
||||
nginx/conf/scgi_params
|
||||
nginx/conf/uwsgi_params
|
||||
nginx/conf/mime.types
|
||||
nginx/conf/scgi_params.default
|
||||
nginx/conf/nginx.conf
|
||||
nginx/conf/uwsgi_params.default
|
||||
nginx/conf/mime.types.default
|
||||
nginx/conf/fastcgi_params.default
|
||||
nginx/sbin/nginx
|
||||
%%LUARESTYDNS%%lualib/resty/dns/resolver.lua
|
||||
%%LUARESTYUPLOAD%%lualib/resty/upload.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha1.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/random.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/md5.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/aes.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha384.lua
|
||||
%%LUARESTYMYSQL%%lualib/resty/mysql.lua
|
||||
%%LUARESTYMEM%%lualib/resty/memcached.lua
|
||||
%%LUARESTYREDIS%%lualib/resty/redis.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha512.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha256.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/string.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha224.lua
|
||||
%%LUARESTYSTRING%%lualib/resty/sha.lua
|
||||
%%LUARDS%%lualib/rds/parser.so
|
||||
%%LUACJSON%%lualib/cjson.so
|
||||
%%LUAREDISPARS%%lualib/redis/parser.so
|
||||
@dirrmtry nginx/sbin
|
||||
@dirrmtry nginx/logs
|
||||
@dirrmtry nginx/html
|
||||
@dirrmtry nginx/conf
|
||||
@dirrmtry nginx
|
||||
%%LUARESTYDNS%%@dirrm lualib/resty/dns
|
||||
@dirrmtry lualib/resty
|
||||
%%LUAREDISPARS%%@dirrmtry lualib/redis
|
||||
%%LUARDS%%@dirrmtry lualib/rds
|
||||
@dirrmtry lualib
|
||||
%%LUA%%@dirrm lua/share/lua/5.1
|
||||
%%LUA%%@dirrm lua/share/lua
|
||||
%%LUA%%@dirrm lua/share
|
||||
%%LUA%%@dirrm lua/lib/lua/5.1
|
||||
%%LUA%%@dirrm lua/lib/lua
|
||||
%%LUA%%@dirrm lua/lib
|
||||
%%LUA%%@dirrm lua/include
|
||||
%%LUA%%@dirrm lua/bin
|
||||
%%LUA%%@dirrm lua
|
||||
%%LUAJIT%%@dirrm luajit/share/luajit-2.0.0-beta10/jit
|
||||
%%LUAJIT%%@dirrm luajit/share/luajit-2.0.0-beta10
|
||||
%%LUAJIT%%@dirrm luajit/include/luajit-2.0
|
||||
%%LUAJIT%%@dirrm luajit/include
|
||||
%%LUAJIT%%@dirrm luajit/share/lua/5.1
|
||||
%%LUAJIT%%@dirrm luajit/share/lua
|
||||
%%LUAJIT%%@dirrm luajit/share
|
||||
%%LUAJIT%%@dirrm luajit/lib/lua/5.1
|
||||
%%LUAJIT%%@dirrm luajit/lib/lua
|
||||
%%LUAJIT%%@dirrm luajit/lib
|
||||
%%LUAJIT%%@dirrm luajit/bin
|
||||
%%LUAJIT%%@dirrm luajit
|
12
Makefile
12
Makefile
|
@ -1,14 +1,16 @@
|
|||
.PHONY: all test try-luajit try-lua
|
||||
.PHONY: all test try-luajit try-lua clean
|
||||
|
||||
all:
|
||||
./util/mirror-tarballs
|
||||
|
||||
test: all
|
||||
prove -r t
|
||||
test:
|
||||
prove -I../test-nginx/lib -r t
|
||||
|
||||
try-luajit: all
|
||||
cd ngx_openresty-`./util/ver` && ./configure --with-luajit
|
||||
cd openresty-`./util/ver` && ./configure --with-luajit
|
||||
|
||||
try-lua: all
|
||||
cd ngx_openresty-`./util/ver` && ./configure && $(MAKE)
|
||||
cd openresty-`./util/ver` && ./configure && $(MAKE)
|
||||
|
||||
clean:
|
||||
rm -rf openresty-*
|
||||
|
|
73
README
73
README
|
@ -1,73 +0,0 @@
|
|||
ngx_openresty is a full-fledged web application server by bundling the standard nginx core,
|
||||
lots of 3rd-party nginx modules, as well as most of their external dependencies.
|
||||
|
||||
This bundle is maintained by us, agentzh and chaoslawful, and sponsored by
|
||||
Taobao.com, Alibaba Group.
|
||||
|
||||
Because most of the nginx modules are developed by the bundle maintainers, it can ensure
|
||||
that all these modules are played well together.
|
||||
|
||||
The bundled software components are copyrighted by the respective copyright holders.
|
||||
|
||||
The homepage for this project is http://openresty.org.
|
||||
|
||||
For users:
|
||||
Visit http://openresty.org/#Download to download the latest bundle tarball, and
|
||||
follow the installation instructions in the page http://openresty.org/#Installation.
|
||||
|
||||
For bundle maintainers:
|
||||
|
||||
The bundle's source is at the following git repository:
|
||||
|
||||
https://github.com/agentzh/ngx_openresty
|
||||
|
||||
To reproduce the bundle tarball, just do
|
||||
|
||||
make
|
||||
|
||||
at the top of the bundle source tree.
|
||||
|
||||
REPORT BUGS
|
||||
|
||||
You're very welcome to report issues on GitHub:
|
||||
|
||||
https://github.com/agentzh/ngx_openresty/issues
|
||||
|
||||
COPYRIGHT & LICENSE
|
||||
|
||||
The bundle itself is licensed under the 2-clause BSD license.
|
||||
|
||||
Copyright (c) 2011, Taobao Inc., Alibaba Group (
|
||||
http://www.taobao.com ).
|
||||
|
||||
Copyright (c) 2011, Yichun "agentzh" Zhang (章亦春)
|
||||
<agentzh@gmail.com>.
|
||||
|
||||
Copyright (c) 2011, Xiaozhe "chaoslawful" Wang (王晓哲)
|
||||
<chaoslawful@gmail.com>.
|
||||
|
||||
This module is licensed under the terms of the BSD license.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
Name
|
||||
====
|
||||
|
||||
OpenResty - Turning Nginx into a Full-Fledged Scriptable Web Platform
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
* [Name](#name)
|
||||
* [Description](#description)
|
||||
* [For Users](#for-users)
|
||||
* [For Bundle Maintainers](#for-bundle-maintainers)
|
||||
* [Additional Features](#additional-features)
|
||||
* [resolv.conf parsing](#resolvconf-parsing)
|
||||
* [Mailing List](#mailing-list)
|
||||
* [Report Bugs](#report-bugs)
|
||||
* [Copyright & License](#copyright--license)
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
OpenResty is a full-fledged web application server by bundling the standard nginx core,
|
||||
lots of 3rd-party nginx modules, as well as most of their external dependencies.
|
||||
|
||||
This bundle is maintained by Yichun Zhang (agentzh).
|
||||
|
||||
Because most of the nginx modules are developed by the bundle maintainers, it can ensure
|
||||
that all these modules are played well together.
|
||||
|
||||
The bundled software components are copyrighted by the respective copyright holders.
|
||||
|
||||
The homepage for this project is on [openresty.org](https://openresty.org/).
|
||||
|
||||
For Users
|
||||
---------
|
||||
|
||||
Visit the [download page](https://openresty.org/en/download.html) on the `openresty.org` web site
|
||||
to download the latest bundle tarball, and
|
||||
follow the installation instructions in the [installation page](https://openresty.org/en/installation.html).
|
||||
|
||||
For Bundle Maintainers
|
||||
----------------------
|
||||
|
||||
The bundle's source is at the following git repository:
|
||||
|
||||
https://github.com/openresty/openresty
|
||||
|
||||
To reproduce the bundle tarball, just do
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
at the top of the bundle source tree.
|
||||
|
||||
Please note that you may need to install some extra dependencies, like `perl`, `dos2unix`, and `mercurial`.
|
||||
On Fedora 22, for example, installing the dependencies
|
||||
is as simple as running the following commands:
|
||||
|
||||
```bash
|
||||
sudo dnf install perl dos2unix mercurial
|
||||
```
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Additional Features
|
||||
===================
|
||||
|
||||
In additional to the standard nginx core features, this bundle also supports the following:
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
resolv.conf parsing
|
||||
--------------------
|
||||
|
||||
**syntax:** *resolver address ... [valid=time] [ipv6=on|off] [local=on|off|path]*
|
||||
|
||||
**default:** *-*
|
||||
|
||||
**context:** *http, stream, server, location*
|
||||
|
||||
Similar to the [`resolver` directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver)
|
||||
in standard nginx core with additional support for parsing additional resolvers from the `resolv.conf` file
|
||||
format.
|
||||
|
||||
When `local=on`, the standard path of `/etc/resolv.conf` will be used. You may also specify arbitrary
|
||||
path to be used for parsing, for example: `local=/tmp/test.conf`.
|
||||
|
||||
When `local=off`, parsing will be disabled (this is the default).
|
||||
|
||||
This feature is not available on Windows platforms.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Mailing List
|
||||
============
|
||||
|
||||
You're very welcome to join the English OpenResty mailing list hosted on Google Groups:
|
||||
|
||||
https://groups.google.com/group/openresty-en
|
||||
|
||||
The Chinese mailing list is here:
|
||||
|
||||
https://groups.google.com/group/openresty
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Report Bugs
|
||||
===========
|
||||
|
||||
You're very welcome to report issues on GitHub:
|
||||
|
||||
https://github.com/openresty/openresty/issues
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Copyright & License
|
||||
===================
|
||||
|
||||
The bundle itself is licensed under the 2-clause BSD license.
|
||||
|
||||
Copyright (c) 2011-2019, Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
|
||||
|
||||
This module is licensed under the terms of the BSD license.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
|
@ -142,10 +142,10 @@ $ClientP._post_by_form = function (url, content, args) {
|
|||
reqId: reqId
|
||||
};
|
||||
_post_forms[reqId] = obj;
|
||||
var submited = false;
|
||||
var submitted = false;
|
||||
// var onloadCount = 0;
|
||||
obj.onload = function() {
|
||||
if (!submited) return;
|
||||
if (!submitted) return;
|
||||
|
||||
// alert('contentLoad ' + (++onloadCount) + ' times\n' + this);
|
||||
|
||||
|
@ -237,7 +237,7 @@ $ClientP._post_by_form = function (url, content, args) {
|
|||
_ipt = null;
|
||||
|
||||
_form.submit();
|
||||
submited = true;
|
||||
submitted = true;
|
||||
};
|
||||
|
||||
$ClientP.post = function (url) {
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<a href="site-binary.tar.gz">Compiled form (.tar.gz)</a>
|
||||
</li>
|
||||
<li class="module-list-item">
|
||||
<a target="_blank" href="http://github.com/agentzh/ngx_openresty/tree/master/demo/[% blog_owner == 'agentzh' ? "Blog" : "Blog2" %]/">
|
||||
<a target="_blank" href="http://github.com/openresty/openresty/tree/master/demo/[% blog_owner == 'agentzh' ? "Blog" : "Blog2" %]/">
|
||||
Source code (Git)
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is a B<Just-In-Time Compiler> (JIT) for the E<rchevron> Lua
|
||||
programming language. Lua is a powerful, dynamic and light-weight
|
||||
programming language. It may be embedded or used as a general-purpose,
|
||||
stand-alone language.
|
||||
|
||||
LuaJIT is Copyright E<copy> 2005-2017 Mike Pall, released under the
|
||||
E<rchevron> MIT open source license.
|
||||
|
||||
=head2 Compatibility
|
||||
|
||||
Windows
|
||||
|
||||
Linux
|
||||
|
||||
BSD
|
||||
|
||||
OSX
|
||||
|
||||
POSIX
|
||||
|
||||
Embedded
|
||||
|
||||
Android
|
||||
|
||||
iOS
|
||||
|
||||
PS3
|
||||
|
||||
PS4
|
||||
|
||||
PS Vita
|
||||
|
||||
Xbox 360
|
||||
|
||||
Xbox One
|
||||
|
||||
GCC
|
||||
|
||||
Clang
|
||||
|
||||
LLVM
|
||||
|
||||
MSVC
|
||||
|
||||
x86
|
||||
|
||||
x64
|
||||
|
||||
ARM
|
||||
|
||||
ARM64
|
||||
|
||||
PPC
|
||||
|
||||
MIPS32
|
||||
|
||||
MIPS64
|
||||
|
||||
Lua 5.1
|
||||
|
||||
API+ABI
|
||||
|
||||
+ JIT
|
||||
|
||||
+ BitOp
|
||||
|
||||
+ FFI
|
||||
|
||||
Drop-in
|
||||
|
||||
DLL/.so
|
||||
|
||||
=head2 Overview
|
||||
|
||||
3x
|
||||
|
||||
- 100x
|
||||
|
||||
115 KB
|
||||
|
||||
VM
|
||||
|
||||
90 KB
|
||||
|
||||
JIT
|
||||
|
||||
63 KLOC
|
||||
|
||||
C
|
||||
|
||||
24 KLOC
|
||||
|
||||
ASM
|
||||
|
||||
11 KLOC
|
||||
|
||||
Lua
|
||||
|
||||
LuaJIT has been successfully used as a B<scripting middleware> in
|
||||
games, appliances, network and graphics apps, numerical simulations,
|
||||
trading platforms and many other specialty applications. It scales from
|
||||
embedded devices, smartphones, desktops up to server farms. It combines
|
||||
high flexibility with E<rchevron> high performance and an unmatched
|
||||
B<low memory footprint>.
|
||||
|
||||
LuaJIT has been in continuous development since 2005. It's widely
|
||||
considered to be B<one of the fastest dynamic language
|
||||
implementations>. It has outperformed other dynamic languages on many
|
||||
cross-language benchmarks since its first release E<mdash> often by a
|
||||
substantial margin.
|
||||
|
||||
For B<LuaJIT 2.0>, the whole VM has been rewritten from the ground up
|
||||
and relentlessly optimized for performance. It combines a B<high-speed
|
||||
interpreter>, written in assembler, with a B<state-of-the-art JIT
|
||||
compiler>.
|
||||
|
||||
An innovative B<trace compiler> is integrated with advanced, SSA-based
|
||||
optimizations and highly tuned code generation backends. A substantial
|
||||
reduction of the overhead associated with dynamic languages allows it
|
||||
to break into the performance range traditionally reserved for offline,
|
||||
static language compilers.
|
||||
|
||||
=head2 More ...
|
||||
|
||||
Please select a sub-topic in the navigation bar to learn more about
|
||||
LuaJIT.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file luajit.html
|
||||
# 8082 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,87 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Contact
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
If you want to report bugs, propose fixes or suggest enhancements,
|
||||
please use the GitHub issue tracker.
|
||||
|
||||
Please send general questions to the E<rchevron> LuaJIT mailing list.
|
||||
|
||||
You can also send any questions you have directly to me:
|
||||
|
||||
Contact info in image
|
||||
|
||||
=head2 Copyright
|
||||
|
||||
All documentation is Copyright E<copy> 2005-2017 Mike Pall.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file contact.html
|
||||
# 2989 bytes of input
|
||||
#Mon May 14 13:19:15 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,176 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Lua/C API Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT
|
||||
include directory must be in the compiler search path (C<-II<path>>) to
|
||||
be able to include the required header for C code:
|
||||
|
||||
#include "luajit.h"
|
||||
|
||||
Or for C++ code:
|
||||
|
||||
#include "lua.hpp"
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, mode)> E<mdash> Control VM
|
||||
|
||||
This is a C API extension to allow control of the VM from C code. The
|
||||
full prototype of C<LuaJIT_setmode> is:
|
||||
|
||||
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
|
||||
|
||||
The returned status is either success (C<1>) or failure (C<0>). The
|
||||
second argument is either C<0> or a stack index (similar to the other
|
||||
Lua/C API functions).
|
||||
|
||||
The third argument specifies the mode, which is 'or'ed with a flag. The
|
||||
flag can be C<LUAJIT_MODE_OFF> to turn a feature off, C<LUAJIT_MODE_ON>
|
||||
to turn a feature on, or C<LUAJIT_MODE_FLUSH> to flush cached code.
|
||||
|
||||
The following modes are defined:
|
||||
|
||||
=head2 C<luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)>
|
||||
|
||||
Turn the whole JIT compiler on or off or flush the whole cache of
|
||||
compiled code.
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)>
|
||||
|
||||
C<luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)>
|
||||
|
||||
C<luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)>
|
||||
|
||||
This sets the mode for the function at the stack index C<idx> or the
|
||||
parent of the calling function (C<idx = 0>). It either enables JIT
|
||||
compilation for a function, disables it and flushes any already
|
||||
compiled code or only flushes already compiled code. This applies
|
||||
recursively to all sub-functions of the function with
|
||||
C<LUAJIT_MODE_ALLFUNC> or only to the sub-functions with
|
||||
C<LUAJIT_MODE_ALLSUBFUNC>.
|
||||
|
||||
=head2 luaJIT_setmode(L, trace,
|
||||
|
||||
LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)
|
||||
|
||||
Flushes the specified root trace and all of its side traces from the
|
||||
cache. The code for the trace will be retained as long as there are any
|
||||
other traces which link to it.
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)>
|
||||
|
||||
This mode defines a wrapper function for calls to C functions. If
|
||||
called with C<LUAJIT_MODE_ON>, the stack index at C<idx> must be a
|
||||
C<lightuserdata> object holding a pointer to the wrapper function. From
|
||||
now on all C functions are called through the wrapper function. If
|
||||
called with C<LUAJIT_MODE_OFF> this mode is turned off and all C
|
||||
functions are directly called.
|
||||
|
||||
The wrapper function can be used for debugging purposes or to catch and
|
||||
convert foreign exceptions. But please read the section on C++
|
||||
exception interoperability first. Recommended usage can be seen in this
|
||||
C++ code excerpt:
|
||||
|
||||
#include <exception>
|
||||
#include "lua.hpp"
|
||||
|
||||
// Catch C++ exceptions and convert them to Lua error messages.
|
||||
// Customize as needed for your own exception classes.
|
||||
static int wrap_exceptions(lua_State *L, lua_CFunction f)
|
||||
{
|
||||
try {
|
||||
return f(L); // Call wrapped function and return result.
|
||||
} catch (const char *s) { // Catch and convert exceptions.
|
||||
lua_pushstring(L, s);
|
||||
} catch (std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
} catch (...) {
|
||||
lua_pushliteral(L, "caught (...)");
|
||||
}
|
||||
return lua_error(L); // Rethrow as a Lua error.
|
||||
}
|
||||
|
||||
static int myinit(lua_State *L)
|
||||
{
|
||||
...
|
||||
// Define wrapper function and enable it.
|
||||
lua_pushlightuserdata(L, (void *)wrap_exceptions);
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
|
||||
lua_pop(L, 1);
|
||||
...
|
||||
}
|
||||
|
||||
Note that you can only define B<a single global wrapper function>, so
|
||||
be careful when using this mechanism from multiple C++ modules. Also
|
||||
note that this mechanism is not without overhead.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_c_api.html
|
||||
# 6042 bytes of input
|
||||
#Mon May 14 13:19:15 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_18) because it has super-phrasal elements (`br_3) as children.
|
|
@ -0,0 +1,285 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
The FFI library allows B<calling external C functions> and B<using C
|
||||
data structures> from pure Lua code.
|
||||
|
||||
The FFI library largely obviates the need to write tedious manual Lua/C
|
||||
bindings in C. No need to learn a separate binding language E<mdash>
|
||||
B<it parses plain C declarations!> These can be cut-n-pasted from C
|
||||
header files or reference manuals. It's up to the task of binding large
|
||||
libraries without the need for dealing with fragile binding generators.
|
||||
|
||||
The FFI library is tightly integrated into LuaJIT (it's not available
|
||||
as a separate module). The code generated by the JIT-compiler for
|
||||
accesses to C data structures from Lua code is on par with the code a C
|
||||
compiler would generate. Calls to C functions can be inlined in
|
||||
JIT-compiled code, unlike calls to functions bound via the classic
|
||||
Lua/C API.
|
||||
|
||||
This page gives a short introduction to the usage of the FFI library.
|
||||
I<Please use the FFI sub-topics in the navigation bar to learn more.>
|
||||
|
||||
=head2 Motivating Example: Calling External C Functions
|
||||
|
||||
It's really easy to call an external C library function:
|
||||
|
||||
â
|
||||
â¡
|
||||
|
||||
|
||||
â¢local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
int printf(const char *fmt, ...);
|
||||
]]
|
||||
ffi.C.printf("Hello %s!", "world")
|
||||
|
||||
So, let's pick that apart:
|
||||
|
||||
Load the FFI library.
|
||||
|
||||
Add a C declaration for the function. The part inside the
|
||||
double-brackets (in green) is just standard C syntax.
|
||||
|
||||
Call the named C function E<mdash> Yes, it's that simple!
|
||||
|
||||
Actually, what goes on behind the scenes is far from simple: makes use
|
||||
of the standard C library namespace C<ffi.C>. Indexing this namespace
|
||||
with a symbol name (C<"printf">) automatically binds it to the standard
|
||||
C library. The result is a special kind of object which, when called,
|
||||
runs the C<printf> function. The arguments passed to this function are
|
||||
automatically converted from Lua objects to the corresponding C types.
|
||||
|
||||
Ok, so maybe the use of C<printf()> wasn't such a spectacular example.
|
||||
You could have done that with C<io.write()> and C<string.format()>,
|
||||
too. But you get the idea ...
|
||||
|
||||
So here's something to pop up a message box on Windows:
|
||||
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
int MessageBoxA(void *w, const char *txt, const char *cap, int type);
|
||||
]]
|
||||
ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
|
||||
|
||||
Bing! Again, that was far too easy, no?
|
||||
|
||||
Compare this with the effort required to bind that function using the
|
||||
classic Lua/C API: create an extra C file, add a C function that
|
||||
retrieves and checks the argument types passed from Lua and calls the
|
||||
actual C function, add a list of module functions and their names, add
|
||||
a C<luaopen_*> function and register all module functions, compile and
|
||||
link it into a shared library (DLL), move it to the proper path, add
|
||||
Lua code that loads the module aaaand ... finally call the binding
|
||||
function. Phew!
|
||||
|
||||
=head2 Motivating Example: Using C Data Structures
|
||||
|
||||
The FFI library allows you to create and access C data structures. Of
|
||||
course the main use for this is for interfacing with C functions. But
|
||||
they can be used stand-alone, too.
|
||||
|
||||
Lua is built upon high-level data types. They are flexible, extensible
|
||||
and dynamic. That's why we all love Lua so much. Alas, this can be
|
||||
inefficient for certain tasks, where you'd really want a low-level data
|
||||
type. E.g. a large array of a fixed structure needs to be implemented
|
||||
with a big table holding lots of tiny tables. This imposes both a
|
||||
substantial memory overhead as well as a performance overhead.
|
||||
|
||||
Here's a sketch of a library that operates on color images plus a
|
||||
simple benchmark. First, the plain Lua version:
|
||||
|
||||
local floor = math.floor
|
||||
|
||||
local function image_ramp_green(n)
|
||||
local img = {}
|
||||
local f = 255/(n-1)
|
||||
for i=1,n do
|
||||
img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=1,n do
|
||||
local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
|
||||
This creates a table with 160.000 pixels, each of which is a table
|
||||
holding four number values in the range of 0-255. First an image with a
|
||||
green ramp is created (1D for simplicity), then the image is converted
|
||||
to greyscale 1000 times. Yes, that's silly, but I was in need of a
|
||||
simple example ...
|
||||
|
||||
And here's the FFI version. The modified parts have been marked in
|
||||
bold:
|
||||
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
â¢
|
||||
â£
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¢
|
||||
â¤local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;
|
||||
]]
|
||||
|
||||
local function image_ramp_green(n)
|
||||
local img = ffi.new("rgba_pixel[?]", n)
|
||||
local f = 255/(n-1)
|
||||
for i=0,n-1 do
|
||||
img[i].green = i*f
|
||||
img[i].alpha = 255
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=0,n-1 do
|
||||
local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
|
||||
Ok, so that wasn't too difficult:
|
||||
|
||||
First, load the FFI library and declare the low-level data type. Here
|
||||
we choose a C<struct> which holds four byte fields, one for each
|
||||
component of a 4x8 bit RGBA pixel.
|
||||
|
||||
Creating the data structure with C<ffi.new()> is straightforward
|
||||
E<mdash> the C<'?'> is a placeholder for the number of elements of a
|
||||
variable-length array.
|
||||
|
||||
C arrays are zero-based, so the indexes have to run from C<0> to
|
||||
C<n-1>. One might want to allocate one more element instead to simplify
|
||||
converting legacy code.
|
||||
|
||||
Since C<ffi.new()> zero-fills the array by default, we only need to set
|
||||
the green and the alpha fields.
|
||||
|
||||
The calls to C<math.floor()> can be omitted here, because
|
||||
floating-point numbers are already truncated towards zero when
|
||||
converting them to an integer. This happens implicitly when the number
|
||||
is stored in the fields of each pixel.
|
||||
|
||||
Now let's have a look at the impact of the changes: first, memory
|
||||
consumption for the image is down from 22 Megabytes to 640 Kilobytes
|
||||
(400*400*4 bytes). That's a factor of 35x less! So, yes, tables do have
|
||||
a noticeable overhead. BTW: The original program would consume 40
|
||||
Megabytes in plain Lua (on x64).
|
||||
|
||||
Next, performance: the pure Lua version runs in 9.57 seconds (52.9
|
||||
seconds with the Lua interpreter) and the FFI version runs in 0.48
|
||||
seconds on my machine (YMMV). That's a factor of 20x faster (110x
|
||||
faster than the Lua interpreter).
|
||||
|
||||
The avid reader may notice that converting the pure Lua version over to
|
||||
use array indexes for the colors (C<[1]> instead of C<.red>, C<[2]>
|
||||
instead of C<.green> etc.) ought to be more compact and faster. This is
|
||||
certainly true (by a factor of ~1.7x). Switching to a struct-of-arrays
|
||||
would help, too.
|
||||
|
||||
However the resulting code would be less idiomatic and rather
|
||||
error-prone. And it still doesn't get even close to the performance of
|
||||
the FFI version of the code. Also, high-level data structures cannot be
|
||||
easily passed to other C functions, especially I/O functions, without
|
||||
undue conversion penalties.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi.html
|
||||
# 10336 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,503 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 C<ffi.*> API Functions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
This page describes the API functions provided by the FFI library in
|
||||
detail. It's recommended to read through the introduction and the FFI
|
||||
tutorial first.
|
||||
|
||||
=head2 Glossary
|
||||
|
||||
=over
|
||||
|
||||
=item * B<cdecl> E<mdash> An abstract C type declaration (a Lua
|
||||
string).
|
||||
|
||||
=item * B<ctype> E<mdash> A C type object. This is a special kind of
|
||||
B<cdata> returned by C<ffi.typeof()>. It serves as a B<cdata>
|
||||
constructor when called.
|
||||
|
||||
=item * B<cdata> E<mdash> A C data object. It holds a value of the
|
||||
corresponding B<ctype>.
|
||||
|
||||
=item * B<ct> E<mdash> A C type specification which can be used for
|
||||
most of the API functions. Either a B<cdecl>, a B<ctype> or a B<cdata>
|
||||
serving as a template type.
|
||||
|
||||
=item * B<cb> E<mdash> A callback object. This is a C data object
|
||||
holding a special function pointer. Calling this function from C code
|
||||
runs an associated Lua function.
|
||||
|
||||
=item * B<VLA> E<mdash> A variable-length array is declared with a C<?>
|
||||
instead of the number of elements, e.g. C<"int[?]">. The number of
|
||||
elements (C<nelem>) must be given when it's created.
|
||||
|
||||
=item * B<VLS> E<mdash> A variable-length struct is a C<struct> C type
|
||||
where the last element is a B<VLA>. The same rules for declaration and
|
||||
creation apply.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Declaring and Accessing External Symbols
|
||||
|
||||
External symbols must be declared first and can then be accessed by
|
||||
indexing a C library namespace, which automatically binds the symbol to
|
||||
a specific library.
|
||||
|
||||
=head2 C<ffi.cdef(def)>
|
||||
|
||||
Adds multiple C declarations for types or external symbols (named
|
||||
variables or functions). C<def> must be a Lua string. It's recommended
|
||||
to use the syntactic sugar for string arguments as follows:
|
||||
|
||||
ffi.cdef[[
|
||||
typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
|
||||
int dofoo(foo_t *f, int n); /* Declare an external C function. */
|
||||
]]
|
||||
|
||||
The contents of the string (the part in green above) must be a sequence
|
||||
of C declarations, separated by semicolons. The trailing semicolon for
|
||||
a single declaration may be omitted.
|
||||
|
||||
Please note that external symbols are only I<declared>, but they are
|
||||
I<not bound> to any specific address, yet. Binding is achieved with C
|
||||
library namespaces (see below).
|
||||
|
||||
C declarations are not passed through a C pre-processor, yet. No
|
||||
pre-processor tokens are allowed, except for C<#pragma pack>. Replace
|
||||
C<#define> in existing C header files with C<enum>, C<static const> or
|
||||
C<typedef> and/or pass the files through an external C pre-processor
|
||||
(once). Be careful not to include unneeded or redundant declarations
|
||||
from unrelated header files.
|
||||
|
||||
=head2 C<ffi.C>
|
||||
|
||||
This is the default C library namespace E<mdash> note the uppercase
|
||||
C<'C'>. It binds to the default set of symbols or libraries on the
|
||||
target system. These are more or less the same as a C compiler would
|
||||
offer by default, without specifying extra link libraries.
|
||||
|
||||
On POSIX systems, this binds to symbols in the default or global
|
||||
namespace. This includes all exported symbols from the executable and
|
||||
any libraries loaded into the global namespace. This includes at least
|
||||
C<libc>, C<libm>, C<libdl> (on Linux), C<libgcc> (if compiled with
|
||||
GCC), as well as any exported symbols from the Lua/C API provided by
|
||||
LuaJIT itself.
|
||||
|
||||
On Windows systems, this binds to symbols exported from the C<*.exe>,
|
||||
the C<lua51.dll> (i.e. the Lua/C API provided by LuaJIT itself), the C
|
||||
runtime library LuaJIT was linked with (C<msvcrt*.dll>),
|
||||
C<kernel32.dll>, C<user32.dll> and C<gdi32.dll>.
|
||||
|
||||
=head2 C<clib = ffi.load(name [,global])>
|
||||
|
||||
This loads the dynamic library given by C<name> and returns a new C
|
||||
library namespace which binds to its symbols. On POSIX systems, if
|
||||
C<global> is C<true>, the library symbols are loaded into the global
|
||||
namespace, too.
|
||||
|
||||
If C<name> is a path, the library is loaded from this path. Otherwise
|
||||
C<name> is canonicalized in a system-dependent way and searched in the
|
||||
default search path for dynamic libraries:
|
||||
|
||||
On POSIX systems, if the name contains no dot, the extension C<.so> is
|
||||
appended. Also, the C<lib> prefix is prepended if necessary. So
|
||||
C<ffi.load("z")> looks for C<"libz.so"> in the default shared library
|
||||
search path.
|
||||
|
||||
On Windows systems, if the name contains no dot, the extension C<.dll>
|
||||
is appended. So C<ffi.load("ws2_32")> looks for C<"ws2_32.dll"> in the
|
||||
default DLL search path.
|
||||
|
||||
=head2 Creating cdata Objects
|
||||
|
||||
The following API functions create cdata objects (C<type()> returns
|
||||
C<"cdata">). All created cdata objects are garbage collected.
|
||||
|
||||
=head2 cdata = ffi.new(ct [,nelem] [,init...])
|
||||
|
||||
cdata = I<ctype>([nelem,] [init...])
|
||||
|
||||
Creates a cdata object for the given C<ct>. VLA/VLS types require the
|
||||
C<nelem> argument. The second syntax uses a ctype as a constructor and
|
||||
is otherwise fully equivalent.
|
||||
|
||||
The cdata object is initialized according to the rules for
|
||||
initializers, using the optional C<init> arguments. Excess initializers
|
||||
cause an error.
|
||||
|
||||
Performance notice: if you want to create many objects of one kind,
|
||||
parse the cdecl only once and get its ctype with C<ffi.typeof()>. Then
|
||||
use the ctype as a constructor repeatedly.
|
||||
|
||||
Please note that an anonymous C<struct> declaration implicitly creates
|
||||
a new and distinguished ctype every time you use it for C<ffi.new()>.
|
||||
This is probably B<not> what you want, especially if you create more
|
||||
than one cdata object. Different anonymous C<structs> are not
|
||||
considered assignment-compatible by the C standard, even though they
|
||||
may have the same fields! Also, they are considered different types by
|
||||
the JIT-compiler, which may cause an excessive number of traces. It's
|
||||
strongly suggested to either declare a named C<struct> or C<typedef>
|
||||
with C<ffi.cdef()> or to create a single ctype object for an anonymous
|
||||
C<struct> with C<ffi.typeof()>.
|
||||
|
||||
=head2 C<ctype = ffi.typeof(ct)>
|
||||
|
||||
Creates a ctype object for the given C<ct>.
|
||||
|
||||
This function is especially useful to parse a cdecl only once and then
|
||||
use the resulting ctype object as a constructor.
|
||||
|
||||
=head2 C<cdata = ffi.cast(ct, init)>
|
||||
|
||||
Creates a scalar cdata object for the given C<ct>. The cdata object is
|
||||
initialized with C<init> using the "cast" variant of the C type
|
||||
conversion rules.
|
||||
|
||||
This functions is mainly useful to override the pointer compatibility
|
||||
checks or to convert pointers to addresses or vice versa.
|
||||
|
||||
=head2 C<ctype = ffi.metatype(ct, metatable)>
|
||||
|
||||
Creates a ctype object for the given C<ct> and associates it with a
|
||||
metatable. Only C<struct>/C<union> types, complex numbers and vectors
|
||||
are allowed. Other types may be wrapped in a C<struct>, if needed.
|
||||
|
||||
The association with a metatable is permanent and cannot be changed
|
||||
afterwards. Neither the contents of the C<metatable> nor the contents
|
||||
of an C<__index> table (if any) may be modified afterwards. The
|
||||
associated metatable automatically applies to all uses of this type, no
|
||||
matter how the objects are created or where they originate from. Note
|
||||
that pre-defined operations on types have precedence (e.g. declared
|
||||
field names cannot be overridden).
|
||||
|
||||
All standard Lua metamethods are implemented. These are called
|
||||
directly, without shortcuts and on any mix of types. For binary
|
||||
operations, the left operand is checked first for a valid ctype
|
||||
metamethod. The C<__gc> metamethod only applies to C<struct>/C<union>
|
||||
types and performs an implicit C<ffi.gc()> call during creation of an
|
||||
instance.
|
||||
|
||||
=head2 C<cdata = ffi.gc(cdata, finalizer)>
|
||||
|
||||
Associates a finalizer with a pointer or aggregate cdata object. The
|
||||
cdata object is returned unchanged.
|
||||
|
||||
This function allows safe integration of unmanaged resources into the
|
||||
automatic memory management of the LuaJIT garbage collector. Typical
|
||||
usage:
|
||||
|
||||
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
|
||||
...
|
||||
p = nil -- Last reference to p is gone.
|
||||
-- GC will eventually run finalizer: ffi.C.free(p)
|
||||
|
||||
A cdata finalizer works like the C<__gc> metamethod for userdata
|
||||
objects: when the last reference to a cdata object is gone, the
|
||||
associated finalizer is called with the cdata object as an argument.
|
||||
The finalizer can be a Lua function or a cdata function or cdata
|
||||
function pointer. An existing finalizer can be removed by setting a
|
||||
C<nil> finalizer, e.g. right before explicitly deleting a resource:
|
||||
|
||||
ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
|
||||
|
||||
=head2 C Type Information
|
||||
|
||||
The following API functions return information about C types. They are
|
||||
most useful for inspecting cdata objects.
|
||||
|
||||
=head2 C<size = ffi.sizeof(ct [,nelem])>
|
||||
|
||||
Returns the size of C<ct> in bytes. Returns C<nil> if the size is not
|
||||
known (e.g. for C<"void"> or function types). Requires C<nelem> for
|
||||
VLA/VLS types, except for cdata objects.
|
||||
|
||||
=head2 C<align = ffi.alignof(ct)>
|
||||
|
||||
Returns the minimum required alignment for C<ct> in bytes.
|
||||
|
||||
=head2 C<ofs [,bpos,bsize] = ffi.offsetof(ct, field)>
|
||||
|
||||
Returns the offset (in bytes) of C<field> relative to the start of
|
||||
C<ct>, which must be a C<struct>. Additionally returns the position and
|
||||
the field size (in bits) for bit fields.
|
||||
|
||||
=head2 C<status = ffi.istype(ct, obj)>
|
||||
|
||||
Returns C<true> if C<obj> has the C type given by C<ct>. Returns
|
||||
C<false> otherwise.
|
||||
|
||||
C type qualifiers (C<const> etc.) are ignored. Pointers are checked
|
||||
with the standard pointer compatibility rules, but without any special
|
||||
treatment for C<void *>. If C<ct> specifies a C<struct>/C<union>, then
|
||||
a pointer to this type is accepted, too. Otherwise the types must match
|
||||
exactly.
|
||||
|
||||
Note: this function accepts all kinds of Lua objects for the C<obj>
|
||||
argument, but always returns C<false> for non-cdata objects.
|
||||
|
||||
=head2 Utility Functions
|
||||
|
||||
=head2 C<err = ffi.errno([newerr])>
|
||||
|
||||
Returns the error number set by the last C function call which
|
||||
indicated an error condition. If the optional C<newerr> argument is
|
||||
present, the error number is set to the new value and the previous
|
||||
value is returned.
|
||||
|
||||
This function offers a portable and OS-independent way to get and set
|
||||
the error number. Note that only I<some> C functions set the error
|
||||
number. And it's only significant if the function actually indicated an
|
||||
error condition (e.g. with a return value of C<-1> or C<NULL>).
|
||||
Otherwise, it may or may not contain any previously set value.
|
||||
|
||||
You're advised to call this function only when needed and as close as
|
||||
possible after the return of the related C function. The C<errno> value
|
||||
is preserved across hooks, memory allocations, invocations of the JIT
|
||||
compiler and other internal VM activity. The same applies to the value
|
||||
returned by C<GetLastError()> on Windows, but you need to declare and
|
||||
call it yourself.
|
||||
|
||||
=head2 C<str = ffi.string(ptr [,len])>
|
||||
|
||||
Creates an interned Lua string from the data pointed to by C<ptr>.
|
||||
|
||||
If the optional argument C<len> is missing, C<ptr> is converted to a
|
||||
C<"char *"> and the data is assumed to be zero-terminated. The length
|
||||
of the string is computed with C<strlen()>.
|
||||
|
||||
Otherwise C<ptr> is converted to a C<"void *"> and C<len> gives the
|
||||
length of the data. The data may contain embedded zeros and need not be
|
||||
byte-oriented (though this may cause endianness issues).
|
||||
|
||||
This function is mainly useful to convert (temporary) C<"const char *">
|
||||
pointers returned by C functions to Lua strings and store them or pass
|
||||
them to other functions expecting a Lua string. The Lua string is an
|
||||
(interned) copy of the data and bears no relation to the original data
|
||||
area anymore. Lua strings are 8 bit clean and may be used to hold
|
||||
arbitrary, non-character data.
|
||||
|
||||
Performance notice: it's faster to pass the length of the string, if
|
||||
it's known. E.g. when the length is returned by a C call like
|
||||
C<sprintf()>.
|
||||
|
||||
=head2 ffi.copy(dst, src, len)
|
||||
|
||||
ffi.copy(dst, str)
|
||||
|
||||
Copies the data pointed to by C<src> to C<dst>. C<dst> is converted to
|
||||
a C<"void *"> and C<src> is converted to a C<"const void *">.
|
||||
|
||||
In the first syntax, C<len> gives the number of bytes to copy. Caveat:
|
||||
if C<src> is a Lua string, then C<len> must not exceed C<#src+1>.
|
||||
|
||||
In the second syntax, the source of the copy must be a Lua string. All
|
||||
bytes of the string I<plus a zero-terminator> are copied to C<dst>
|
||||
(i.e. C<#src+1> bytes).
|
||||
|
||||
Performance notice: C<ffi.copy()> may be used as a faster (inlinable)
|
||||
replacement for the C library functions C<memcpy()>, C<strcpy()> and
|
||||
C<strncpy()>.
|
||||
|
||||
=head2 C<ffi.fill(dst, len [,c])>
|
||||
|
||||
Fills the data pointed to by C<dst> with C<len> constant bytes, given
|
||||
by C<c>. If C<c> is omitted, the data is zero-filled.
|
||||
|
||||
Performance notice: C<ffi.fill()> may be used as a faster (inlinable)
|
||||
replacement for the C library function C<memset(dst, c, len)>. Please
|
||||
note the different order of arguments!
|
||||
|
||||
=head2 Target-specific Information
|
||||
|
||||
=head2 C<status = ffi.abi(param)>
|
||||
|
||||
Returns C<true> if C<param> (a Lua string) applies for the target ABI
|
||||
(Application Binary Interface). Returns C<false> otherwise. The
|
||||
following parameters are currently defined:
|
||||
|
||||
Parameter
|
||||
|
||||
Description
|
||||
|
||||
32bit
|
||||
|
||||
32 bit architecture
|
||||
|
||||
64bit
|
||||
|
||||
64 bit architecture
|
||||
|
||||
le
|
||||
|
||||
Little-endian architecture
|
||||
|
||||
be
|
||||
|
||||
Big-endian architecture
|
||||
|
||||
fpu
|
||||
|
||||
Target has a hardware FPU
|
||||
|
||||
softfp
|
||||
|
||||
softfp calling conventions
|
||||
|
||||
hardfp
|
||||
|
||||
hardfp calling conventions
|
||||
|
||||
eabi
|
||||
|
||||
EABI variant of the standard ABI
|
||||
|
||||
win
|
||||
|
||||
Windows variant of the standard ABI
|
||||
|
||||
gc64
|
||||
|
||||
64 bit GC references
|
||||
|
||||
=head2 C<ffi.os>
|
||||
|
||||
Contains the target OS name. Same contents as C<jit.os>.
|
||||
|
||||
=head2 C<ffi.arch>
|
||||
|
||||
Contains the target architecture name. Same contents as C<jit.arch>.
|
||||
|
||||
=head2 Methods for Callbacks
|
||||
|
||||
The C types for callbacks have some extra methods:
|
||||
|
||||
=head2 C<cb:free()>
|
||||
|
||||
Free the resources associated with a callback. The associated Lua
|
||||
function is unanchored and may be garbage collected. The callback
|
||||
function pointer is no longer valid and must not be called anymore (it
|
||||
may be reused by a subsequently created callback).
|
||||
|
||||
=head2 C<cb:set(func)>
|
||||
|
||||
Associate a new Lua function with a callback. The C type of the
|
||||
callback and the callback function pointer are unchanged.
|
||||
|
||||
This method is useful to dynamically switch the receiver of callbacks
|
||||
without creating a new callback each time and registering it again
|
||||
(e.g. with a GUI library).
|
||||
|
||||
=head2 Extended Standard Library Functions
|
||||
|
||||
The following standard library functions have been extended to work
|
||||
with cdata objects:
|
||||
|
||||
=head2 C<n = tonumber(cdata)>
|
||||
|
||||
Converts a number cdata object to a C<double> and returns it as a Lua
|
||||
number. This is particularly useful for boxed 64 bit integer values.
|
||||
Caveat: this conversion may incur a precision loss.
|
||||
|
||||
=head2 C<s = tostring(cdata)>
|
||||
|
||||
Returns a string representation of the value of 64 bit integers
|
||||
(C<B<">nnnB<LL">> or C<B<">nnnB<ULL">>) or complex numbers
|
||||
(C<B<">reE<plusmn>imB<i">>). Otherwise returns a string representation
|
||||
of the C type of a ctype object (C<B<"ctypeE<lt>>typeB<E<gt>">>) or a
|
||||
cdata object (C<B<"cdataE<lt>>typeB<E<gt>: >address">), unless you
|
||||
override it with a C<__tostring> metamethod (see C<ffi.metatype()>).
|
||||
|
||||
=head2 iter, obj, start = pairs(cdata)
|
||||
|
||||
iter, obj, start = ipairs(cdata)
|
||||
|
||||
Calls the C<__pairs> or C<__ipairs> metamethod of the corresponding
|
||||
ctype.
|
||||
|
||||
=head2 Extensions to the Lua Parser
|
||||
|
||||
The parser for Lua source code treats numeric literals with the
|
||||
suffixes C<LL> or C<ULL> as signed or unsigned 64 bit integers. Case
|
||||
doesn't matter, but uppercase is recommended for readability. It
|
||||
handles decimal (C<42LL>), hexadecimal (C<0x2aLL>) and binary
|
||||
(C<0b101010LL>) literals.
|
||||
|
||||
The imaginary part of complex numbers can be specified by suffixing
|
||||
number literals with C<i> or C<I>, e.g. C<12.5i>. Caveat: you'll need
|
||||
to use C<1i> to get an imaginary part with the value one, since C<i>
|
||||
itself still refers to a variable named C<i>.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi_api.html
|
||||
# 21471 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_157) because it has super-phrasal elements (`br_3, `br_4) as children.
|
||||
# Deleting phrasal "code" element (`tt_113) because it has super-phrasal elements (`br_2) as children.
|
||||
# Deleting phrasal "code" element (`tt_41) because it has super-phrasal elements (`br_1) as children.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,640 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 FFI Tutorial
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
This page is intended to give you an overview of the features of the
|
||||
FFI library by presenting a few use cases and guidelines.
|
||||
|
||||
This page makes no attempt to explain all of the FFI library, though.
|
||||
You'll want to have a look at the ffi.* API function reference and the
|
||||
FFI semantics to learn more.
|
||||
|
||||
=head2 Loading the FFI Library
|
||||
|
||||
The FFI library is built into LuaJIT by default, but it's not loaded
|
||||
and initialized by default. The suggested way to use the FFI library is
|
||||
to add the following to the start of every Lua file that needs one of
|
||||
its functions:
|
||||
|
||||
local ffi = require("ffi")
|
||||
|
||||
Please note this doesn't define an C<ffi> variable in the table of
|
||||
globals E<mdash> you really need to use the local variable. The
|
||||
C<require> function ensures the library is only loaded once.
|
||||
|
||||
Note: If you want to experiment with the FFI from the interactive
|
||||
prompt of the command line executable, omit the C<local>, as it doesn't
|
||||
preserve local variables across lines.
|
||||
|
||||
=head2 Accessing Standard System Functions
|
||||
|
||||
The following code explains how to access standard system functions. We
|
||||
slowly print two lines of dots by sleeping for 10 milliseconds after
|
||||
each dot:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
â¢
|
||||
â£
|
||||
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¥local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
void Sleep(int ms);
|
||||
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
|
||||
]]
|
||||
|
||||
local sleep
|
||||
if ffi.os == "Windows" then
|
||||
function sleep(s)
|
||||
ffi.C.Sleep(s*1000)
|
||||
end
|
||||
else
|
||||
function sleep(s)
|
||||
ffi.C.poll(nil, 0, s*1000)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,160 do
|
||||
io.write("."); io.flush()
|
||||
sleep(0.01)
|
||||
end
|
||||
io.write("\n")
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines the C library functions we're going to use. The part
|
||||
inside the double-brackets (in green) is just standard C syntax. You
|
||||
can usually get this info from the C header files or the documentation
|
||||
provided by each C library or C compiler.
|
||||
|
||||
The difficulty we're facing here, is that there are different standards
|
||||
to choose from. Windows has a simple C<Sleep()> function. On other
|
||||
systems there are a variety of functions available to achieve
|
||||
sub-second sleeps, but with no clear consensus. Thankfully C<poll()>
|
||||
can be used for this task, too, and it's present on most non-Windows
|
||||
systems. The check for C<ffi.os> makes sure we use the Windows-specific
|
||||
function only on Windows systems.
|
||||
|
||||
Here we're wrapping the call to the C function in a Lua function. This
|
||||
isn't strictly necessary, but it's helpful to deal with system-specific
|
||||
issues only in one part of the code. The way we're wrapping it ensures
|
||||
the check for the OS is only done during initialization and not for
|
||||
every call.
|
||||
|
||||
A more subtle point is that we defined our C<sleep()> function (for the
|
||||
sake of this example) as taking the number of seconds, but accepting
|
||||
fractional seconds. Multiplying this by 1000 gets us milliseconds, but
|
||||
that still leaves it a Lua number, which is a floating-point value.
|
||||
Alas, the C<Sleep()> function only accepts an integer value. Luckily
|
||||
for us, the FFI library automatically performs the conversion when
|
||||
calling the function (truncating the FP value towards zero, like in C).
|
||||
|
||||
Some readers will notice that C<Sleep()> is part of C<KERNEL32.DLL> and
|
||||
is also a C<stdcall> function. So how can this possibly work? The FFI
|
||||
library provides the C<ffi.C> default C library namespace, which allows
|
||||
calling functions from the default set of libraries, like a C compiler
|
||||
would. Also, the FFI library automatically detects C<stdcall>
|
||||
functions, so you don't need to declare them as such.
|
||||
|
||||
The C<poll()> function takes a couple more arguments we're not going to
|
||||
use. You can simply use C<nil> to pass a C<NULL> pointer and C<0> for
|
||||
the C<nfds> parameter. Please note that the number C<0> I<does not
|
||||
convert to a pointer value>, unlike in C++. You really have to pass
|
||||
pointers to pointer arguments and numbers to number arguments.
|
||||
|
||||
The page on FFI semantics has all of the gory details about conversions
|
||||
between Lua objects and C types. For the most part you don't have to
|
||||
deal with this, as it's performed automatically and it's carefully
|
||||
designed to bridge the semantic differences between Lua and C.
|
||||
|
||||
Now that we have defined our own C<sleep()> function, we can just call
|
||||
it from plain Lua code. That wasn't so bad, huh? Turning these boring
|
||||
animated dots into a fascinating best-selling game is left as an
|
||||
exercise for the reader. :-)
|
||||
|
||||
=head2 Accessing the zlib Compression Library
|
||||
|
||||
The following code shows how to access the zlib compression library
|
||||
from Lua code. We'll define two convenience wrapper functions that take
|
||||
a string and compress or uncompress it to another string:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
|
||||
â¢
|
||||
|
||||
â£
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
|
||||
â¥
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¦local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
unsigned long compressBound(unsigned long sourceLen);
|
||||
int compress2(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen, int level);
|
||||
int uncompress(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen);
|
||||
]]
|
||||
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
|
||||
|
||||
local function compress(txt)
|
||||
local n = zlib.compressBound(#txt)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.compress2(buf, buflen, txt, #txt, 9)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
local function uncompress(comp, n)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.uncompress(buf, buflen, comp, #comp)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
-- Simple test code.
|
||||
local txt = string.rep("abcd", 1000)
|
||||
print("Uncompressed size: ", #txt)
|
||||
local c = compress(txt)
|
||||
print("Compressed size: ", #c)
|
||||
local txt2 = uncompress(c, #txt)
|
||||
assert(txt2 == txt)
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines some of the C functions provided by zlib. For the sake of
|
||||
this example, some type indirections have been reduced and it uses the
|
||||
pre-defined fixed-size integer types, while still adhering to the zlib
|
||||
API/ABI.
|
||||
|
||||
This loads the zlib shared library. On POSIX systems it's named
|
||||
C<libz.so> and usually comes pre-installed. Since C<ffi.load()>
|
||||
automatically adds any missing standard prefixes/suffixes, we can
|
||||
simply load the C<"z"> library. On Windows it's named C<zlib1.dll> and
|
||||
you'll have to download it first from the E<rchevron> zlib site. The
|
||||
check for C<ffi.os> makes sure we pass the right name to C<ffi.load()>.
|
||||
|
||||
First, the maximum size of the compression buffer is obtained by
|
||||
calling the C<zlib.compressBound> function with the length of the
|
||||
uncompressed string. The next line allocates a byte buffer of this
|
||||
size. The C<[?]> in the type specification indicates a variable-length
|
||||
array (VLA). The actual number of elements of this array is given as
|
||||
the 2nd argument to C<ffi.new()>.
|
||||
|
||||
This may look strange at first, but have a look at the declaration of
|
||||
the C<compress2> function from zlib: the destination length is defined
|
||||
as a pointer! This is because you pass in the maximum buffer size and
|
||||
get back the actual length that was used.
|
||||
|
||||
In C you'd pass in the address of a local variable (C<&buflen>). But
|
||||
since there's no address-of operator in Lua, we'll just pass in a
|
||||
one-element array. Conveniently it can be initialized with the maximum
|
||||
buffer size in one step. Calling the actual C<zlib.compress2> function
|
||||
is then straightforward.
|
||||
|
||||
We want to return the compressed data as a Lua string, so we'll use
|
||||
C<ffi.string()>. It needs a pointer to the start of the data and the
|
||||
actual length. The length has been returned in the C<buflen> array, so
|
||||
we'll just get it from there.
|
||||
|
||||
Note that since the function returns now, the C<buf> and C<buflen>
|
||||
variables will eventually be garbage collected. This is fine, because
|
||||
C<ffi.string()> has copied the contents to a newly created (interned)
|
||||
Lua string. If you plan to call this function lots of times, consider
|
||||
reusing the buffers and/or handing back the results in buffers instead
|
||||
of strings. This will reduce the overhead for garbage collection and
|
||||
string interning.
|
||||
|
||||
The C<uncompress> functions does the exact opposite of the C<compress>
|
||||
function. The compressed data doesn't include the size of the original
|
||||
string, so this needs to be passed in. Otherwise no surprises here.
|
||||
|
||||
The code, that makes use of the functions we just defined, is just
|
||||
plain Lua code. It doesn't need to know anything about the LuaJIT FFI
|
||||
E<mdash> the convenience wrapper functions completely hide it.
|
||||
|
||||
One major advantage of the LuaJIT FFI is that you are now able to write
|
||||
those wrappers I<in Lua>. And at a fraction of the time it would cost
|
||||
you to create an extra C module using the Lua/C API. Many of the
|
||||
simpler C functions can probably be used directly from your Lua code,
|
||||
without any wrappers.
|
||||
|
||||
Side note: the zlib API uses the C<long> type for passing lengths and
|
||||
sizes around. But all those zlib functions actually only deal with 32
|
||||
bit values. This is an unfortunate choice for a public API, but may be
|
||||
explained by zlib's history E<mdash> we'll just have to deal with it.
|
||||
|
||||
First, you should know that a C<long> is a 64 bit type e.g. on
|
||||
POSIX/x64 systems, but a 32 bit type on Windows/x64 and on 32 bit
|
||||
systems. Thus a C<long> result can be either a plain Lua number or a
|
||||
boxed 64 bit integer cdata object, depending on the target system.
|
||||
|
||||
Ok, so the C<ffi.*> functions generally accept cdata objects wherever
|
||||
you'd want to use a number. That's why we get a away with passing C<n>
|
||||
to C<ffi.string()> above. But other Lua library functions or modules
|
||||
don't know how to deal with this. So for maximum portability one needs
|
||||
to use C<tonumber()> on returned C<long> results before passing them
|
||||
on. Otherwise the application might work on some systems, but would
|
||||
fail in a POSIX/x64 environment.
|
||||
|
||||
=head2 Defining Metamethods for a C Type
|
||||
|
||||
The following code explains how to define metamethods for a C type. We
|
||||
define a simple point type and add some operations to it:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
â¢
|
||||
|
||||
â£
|
||||
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
â¥local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
typedef struct { double x, y; } point_t;
|
||||
]]
|
||||
|
||||
local point
|
||||
local mt = {
|
||||
__add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
|
||||
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
|
||||
__index = {
|
||||
area = function(a) return a.x*a.x + a.y*a.y end,
|
||||
},
|
||||
}
|
||||
point = ffi.metatype("point_t", mt)
|
||||
|
||||
local a = point(3, 4)
|
||||
print(a.x, a.y) --> 3 4
|
||||
print(#a) --> 5
|
||||
print(a:area()) --> 25
|
||||
local b = a + point(0.5, 8)
|
||||
print(#b) --> 12.5
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines the C type for a two-dimensional point object.
|
||||
|
||||
We have to declare the variable holding the point constructor first,
|
||||
because it's used inside of a metamethod.
|
||||
|
||||
Let's define an C<__add> metamethod which adds the coordinates of two
|
||||
points and creates a new point object. For simplicity, this function
|
||||
assumes that both arguments are points. But it could be any mix of
|
||||
objects, if at least one operand is of the required type (e.g. adding a
|
||||
point plus a number or vice versa). Our C<__len> metamethod returns the
|
||||
distance of a point to the origin.
|
||||
|
||||
If we run out of operators, we can define named methods, too. Here the
|
||||
C<__index> table defines an C<area> function. For custom indexing
|
||||
needs, one might want to define C<__index> and C<__newindex>
|
||||
I<functions> instead.
|
||||
|
||||
This associates the metamethods with our C type. This only needs to be
|
||||
done once. For convenience, a constructor is returned by
|
||||
C<ffi.metatype()>. We're not required to use it, though. The original C
|
||||
type can still be used e.g. to create an array of points. The
|
||||
metamethods automatically apply to any and all uses of this type.
|
||||
|
||||
Please note that the association with a metatable is permanent and
|
||||
B<the metatable must not be modified afterwards!> Ditto for the
|
||||
C<__index> table.
|
||||
|
||||
Here are some simple usage examples for the point type and their
|
||||
expected results. The pre-defined operations (such as C<a.x>) can be
|
||||
freely mixed with the newly defined metamethods. Note that C<area> is a
|
||||
method and must be called with the Lua syntax for methods: C<a:area()>,
|
||||
not C<a.area()>.
|
||||
|
||||
The C type metamethod mechanism is most useful when used in conjunction
|
||||
with C libraries that are written in an object-oriented style. Creators
|
||||
return a pointer to a new instance and methods take an instance pointer
|
||||
as the first argument. Sometimes you can just point C<__index> to the
|
||||
library namespace and C<__gc> to the destructor and you're done. But
|
||||
often enough you'll want to add convenience wrappers, e.g. to return
|
||||
actual Lua strings or when returning multiple values.
|
||||
|
||||
Some C libraries only declare instance pointers as an opaque C<void *>
|
||||
type. In this case you can use a fake type for all declarations, e.g. a
|
||||
pointer to a named (incomplete) struct will do: C<typedef struct
|
||||
foo_type *foo_handle>. The C side doesn't know what you declare with
|
||||
the LuaJIT FFI, but as long as the underlying types are compatible,
|
||||
everything still works.
|
||||
|
||||
=head2 Translating C Idioms
|
||||
|
||||
Here's a list of common C idioms and their translation to the LuaJIT
|
||||
FFI:
|
||||
|
||||
Idiom
|
||||
|
||||
C code
|
||||
|
||||
Lua code
|
||||
|
||||
Pointer dereference
|
||||
|
||||
C<int *p;>
|
||||
|
||||
x = *p;
|
||||
|
||||
*p = y;
|
||||
|
||||
x = B<p[0]>
|
||||
|
||||
B<p[0]> = y
|
||||
|
||||
Pointer indexing
|
||||
|
||||
C<int i, *p;>
|
||||
|
||||
x = p[i];
|
||||
|
||||
p[i+1] = y;
|
||||
|
||||
x = p[i]
|
||||
|
||||
p[i+1] = y
|
||||
|
||||
Array indexing
|
||||
|
||||
C<int i, a[];>
|
||||
|
||||
x = a[i];
|
||||
|
||||
a[i+1] = y;
|
||||
|
||||
x = a[i]
|
||||
|
||||
a[i+1] = y
|
||||
|
||||
C<struct>/C<union> dereference
|
||||
|
||||
C<struct foo s;>
|
||||
|
||||
x = s.field;
|
||||
|
||||
s.field = y;
|
||||
|
||||
x = s.field
|
||||
|
||||
s.field = y
|
||||
|
||||
C<struct>/C<union> pointer deref.
|
||||
|
||||
C<struct foo *sp;>
|
||||
|
||||
x = sp-E<gt>field;
|
||||
|
||||
sp-E<gt>field = y;
|
||||
|
||||
x = B<s.field>
|
||||
|
||||
B<s.field> = y
|
||||
|
||||
Pointer arithmetic
|
||||
|
||||
C<int i, *p;>
|
||||
|
||||
x = p + i;
|
||||
|
||||
y = p - i;
|
||||
|
||||
x = p + i
|
||||
|
||||
y = p - i
|
||||
|
||||
Pointer difference
|
||||
|
||||
C<int *p1, *p2;>
|
||||
|
||||
C<x = p1 - p2;>
|
||||
|
||||
C<x = p1 - p2>
|
||||
|
||||
Array element pointer
|
||||
|
||||
C<int i, a[];>
|
||||
|
||||
C<x = &a[i];>
|
||||
|
||||
C<x = B<a+i>>
|
||||
|
||||
Cast pointer to address
|
||||
|
||||
C<int *p;>
|
||||
|
||||
C<x = (intptr_t)p;>
|
||||
|
||||
x = tonumber(
|
||||
|
||||
ffi.cast("intptr_t",
|
||||
|
||||
p))
|
||||
|
||||
Functions with outargs
|
||||
|
||||
C<void foo(int *inoutlen);>
|
||||
|
||||
int len = x;
|
||||
|
||||
foo(&len);
|
||||
|
||||
y = len;
|
||||
|
||||
local len =
|
||||
|
||||
ffi.new("int[1]", x)
|
||||
|
||||
foo(len)
|
||||
|
||||
y = len[0]
|
||||
|
||||
Vararg conversions
|
||||
|
||||
C<int printf(char *fmt, ...);>
|
||||
|
||||
printf("%g", 1.0);
|
||||
|
||||
printf("%d", 1);
|
||||
|
||||
printf("%g", 1);
|
||||
|
||||
printf("%d",
|
||||
|
||||
B<ffi.new("int", 1)>)
|
||||
|
||||
=head2 To Cache or Not to Cache
|
||||
|
||||
It's a common Lua idiom to cache library functions in local variables
|
||||
or upvalues, e.g.:
|
||||
|
||||
local byte, char = string.byte, string.char
|
||||
local function foo(x)
|
||||
return char(byte(x)+1)
|
||||
end
|
||||
|
||||
This replaces several hash-table lookups with a (faster) direct use of
|
||||
a local or an upvalue. This is less important with LuaJIT, since the
|
||||
JIT compiler optimizes hash-table lookups a lot and is even able to
|
||||
hoist most of them out of the inner loops. It can't eliminate I<all> of
|
||||
them, though, and it saves some typing for often-used functions. So
|
||||
there's still a place for this, even with LuaJIT.
|
||||
|
||||
The situation is a bit different with C function calls via the FFI
|
||||
library. The JIT compiler has special logic to eliminate I<all of the
|
||||
lookup overhead> for functions resolved from a C library namespace!
|
||||
Thus it's not helpful and actually counter-productive to cache
|
||||
individual C functions like this:
|
||||
|
||||
local funca, funcb = ffi.C.funca, ffi.C.funcb -- Not helpful!
|
||||
local function foo(x, n)
|
||||
for i=1,n do funcb(funca(x, i), 1) end
|
||||
end
|
||||
|
||||
This turns them into indirect calls and generates bigger and slower
|
||||
machine code. Instead you'll want to cache the namespace itself and
|
||||
rely on the JIT compiler to eliminate the lookups:
|
||||
|
||||
local C = ffi.C -- Instead use this!
|
||||
local function foo(x, n)
|
||||
for i=1,n do C.funcb(C.funca(x, i), 1) end
|
||||
end
|
||||
|
||||
This generates both shorter and faster code. So B<don't cache C
|
||||
functions>, but B<do> cache namespaces! Most often the namespace is
|
||||
already in a local variable at an outer scope, e.g. from C<local lib =
|
||||
ffi.load(...)>. Note that copying it to a local variable in the
|
||||
function scope is unnecessary.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi_tutorial.html
|
||||
# 22557 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_100) because it has super-phrasal elements (`br_33, `br_34) as children.
|
||||
# Deleting phrasal "code" element (`tt_99) because it has super-phrasal elements (`br_31, `br_32) as children.
|
||||
# Deleting phrasal "b" element (`b_8) because it has super-phrasal elements (`br_27, `br_28, `br_29) as children.
|
||||
# Deleting phrasal "code" element (`tt_97) because it has super-phrasal elements (`br_27, `br_28, `br_29) as children.
|
||||
# Deleting phrasal "code" element (`tt_96) because it has super-phrasal elements (`br_25, `br_26) as children.
|
||||
# Deleting phrasal "b" element (`b_7) because it has super-phrasal elements (`br_22, `br_23) as children.
|
||||
# Deleting phrasal "code" element (`tt_94) because it has super-phrasal elements (`br_22, `br_23) as children.
|
||||
# Deleting phrasal "code" element (`tt_85) because it has super-phrasal elements (`br_18) as children.
|
||||
# Deleting phrasal "code" element (`tt_84) because it has super-phrasal elements (`br_17) as children.
|
||||
# Deleting phrasal "code" element (`tt_82) because it has super-phrasal elements (`br_15) as children.
|
||||
# Deleting phrasal "code" element (`tt_81) because it has super-phrasal elements (`br_14) as children.
|
||||
# Deleting phrasal "code" element (`tt_77) because it has super-phrasal elements (`br_12) as children.
|
||||
# Deleting phrasal "code" element (`tt_76) because it has super-phrasal elements (`br_11) as children.
|
||||
# Deleting phrasal "code" element (`tt_72) because it has super-phrasal elements (`br_9) as children.
|
||||
# Deleting phrasal "code" element (`tt_71) because it has super-phrasal elements (`br_8) as children.
|
||||
# Deleting phrasal "code" element (`tt_69) because it has super-phrasal elements (`br_6) as children.
|
||||
# Deleting phrasal "code" element (`tt_68) because it has super-phrasal elements (`br_5) as children.
|
||||
# Deleting phrasal "code" element (`tt_66) because it has super-phrasal elements (`br_3) as children.
|
||||
# Deleting phrasal "code" element (`tt_65) because it has super-phrasal elements (`br_2) as children.
|
|
@ -0,0 +1,182 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 C<jit.*> Library
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
The functions in this built-in module control the behavior of the JIT
|
||||
compiler engine. Note that JIT-compilation is fully automatic E<mdash>
|
||||
you probably won't need to use any of the following functions unless
|
||||
you have special needs.
|
||||
|
||||
=head2 jit.on()
|
||||
|
||||
jit.off()
|
||||
|
||||
Turns the whole JIT compiler on (default) or off.
|
||||
|
||||
These functions are typically used with the command line options C<-j
|
||||
on> or C<-j off>.
|
||||
|
||||
=head2 C<jit.flush()>
|
||||
|
||||
Flushes the whole cache of compiled code.
|
||||
|
||||
=head2 jit.on(func|true [,true|false])
|
||||
|
||||
jit.off(func|true [,true|false])
|
||||
|
||||
jit.flush(func|true [,true|false])
|
||||
|
||||
C<jit.on> enables JIT compilation for a Lua function (this is the
|
||||
default).
|
||||
|
||||
C<jit.off> disables JIT compilation for a Lua function and flushes any
|
||||
already compiled code from the code cache.
|
||||
|
||||
C<jit.flush> flushes the code, but doesn't affect the enable/disable
|
||||
status.
|
||||
|
||||
The current function, i.e. the Lua function calling this library
|
||||
function, can also be specified by passing C<true> as the first
|
||||
argument.
|
||||
|
||||
If the second argument is C<true>, JIT compilation is also enabled,
|
||||
disabled or flushed recursively for all sub-functions of a function.
|
||||
With C<false> only the sub-functions are affected.
|
||||
|
||||
The C<jit.on> and C<jit.off> functions only set a flag which is checked
|
||||
when the function is about to be compiled. They do not trigger
|
||||
immediate compilation.
|
||||
|
||||
Typical usage is C<jit.off(true, true)> in the main chunk of a module
|
||||
to turn off JIT compilation for the whole module for debugging
|
||||
purposes.
|
||||
|
||||
=head2 C<jit.flush(tr)>
|
||||
|
||||
Flushes the root trace, specified by its number, and all of its side
|
||||
traces from the cache. The code for the trace will be retained as long
|
||||
as there are any other traces which link to it.
|
||||
|
||||
=head2 C<status, ... = jit.status()>
|
||||
|
||||
Returns the current status of the JIT compiler. The first result is
|
||||
either C<true> or C<false> if the JIT compiler is turned on or off. The
|
||||
remaining results are strings for CPU-specific features and enabled
|
||||
optimizations.
|
||||
|
||||
=head2 C<jit.version>
|
||||
|
||||
Contains the LuaJIT version string.
|
||||
|
||||
=head2 C<jit.version_num>
|
||||
|
||||
Contains the version number of the LuaJIT core. Version xx.yy.zz is
|
||||
represented by the decimal number xxyyzz.
|
||||
|
||||
=head2 C<jit.os>
|
||||
|
||||
Contains the target OS name: "Windows", "Linux", "OSX", "BSD", "POSIX"
|
||||
or "Other".
|
||||
|
||||
=head2 C<jit.arch>
|
||||
|
||||
Contains the target architecture name: "x86", "x64", "arm", "arm64",
|
||||
"ppc", "mips" or "mips64".
|
||||
|
||||
=head2 C<jit.opt.*> E<mdash> JIT compiler optimization control
|
||||
|
||||
This sub-module provides the backend for the C<-O> command line option.
|
||||
|
||||
You can also use it programmatically, e.g.:
|
||||
|
||||
jit.opt.start(2) -- same as -O2
|
||||
jit.opt.start("-dce")
|
||||
jit.opt.start("hotloop=10", "hotexit=2")
|
||||
|
||||
Unlike in LuaJIT 1.x, the module is built-in and B<optimization is
|
||||
turned on by default!> It's no longer necessary to run
|
||||
C<require("jit.opt").start()>, which was one of the ways to enable
|
||||
optimization.
|
||||
|
||||
=head2 C<jit.util.*> E<mdash> JIT compiler introspection
|
||||
|
||||
This sub-module holds functions to introspect the bytecode, generated
|
||||
traces, the IR and the generated machine code. The functionality
|
||||
provided by this module is still in flux and therefore undocumented.
|
||||
|
||||
The debug modules C<-jbc>, C<-jv> and C<-jdump> make extensive use of
|
||||
these functions. Please check out their source code, if you want to
|
||||
know more.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_jit.html
|
||||
# 5903 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_6) because it has super-phrasal elements (`br_2, `br_3) as children.
|
||||
# Deleting phrasal "code" element (`tt_2) because it has super-phrasal elements (`br_1) as children.
|
|
@ -0,0 +1,358 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Profiler
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT has an integrated statistical profiler with very low overhead.
|
||||
It allows sampling the currently executing stack and other parameters
|
||||
in regular intervals.
|
||||
|
||||
The integrated profiler can be accessed from three levels:
|
||||
|
||||
=over
|
||||
|
||||
=item * The bundled high-level profiler, invoked by the C<-jp> command
|
||||
line option.
|
||||
|
||||
=item * A low-level Lua API to control the profiler.
|
||||
|
||||
=item * A low-level C API to control the profiler.
|
||||
|
||||
=back
|
||||
|
||||
=head2 High-Level Profiler
|
||||
|
||||
The bundled high-level profiler offers basic profiling functionality.
|
||||
It generates simple textual summaries or source code annotations. It
|
||||
can be accessed with the C<-jp> command line option or from Lua code by
|
||||
loading the underlying C<jit.p> module.
|
||||
|
||||
To cut to the chase E<mdash> run this to get a CPU usage profile by
|
||||
function name:
|
||||
|
||||
luajit -jp myapp.lua
|
||||
|
||||
It's I<not> a stated goal of the bundled profiler to add every possible
|
||||
option or to cater for special profiling needs. The low-level profiler
|
||||
APIs are documented below. They may be used by third-party authors to
|
||||
implement advanced functionality, e.g. IDE integration or graphical
|
||||
profilers.
|
||||
|
||||
Note: Sampling works for both interpreted and JIT-compiled code. The
|
||||
results for JIT-compiled code may sometimes be surprising. LuaJIT
|
||||
heavily optimizes and inlines Lua code E<mdash> there's no simple
|
||||
one-to-one correspondence between source code lines and the sampled
|
||||
machine code.
|
||||
|
||||
=head2 C<-jp=[options[,output]]>
|
||||
|
||||
The C<-jp> command line option starts the high-level profiler. When the
|
||||
application run by the command line terminates, the profiler stops and
|
||||
writes the results to C<stdout> or to the specified C<output> file.
|
||||
|
||||
The C<options> argument specifies how the profiling is to be performed:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<f> E<mdash> Stack dump: function name, otherwise module:line.
|
||||
This is the default mode.
|
||||
|
||||
=item * C<F> E<mdash> Stack dump: ditto, but dump module:name.
|
||||
|
||||
=item * C<l> E<mdash> Stack dump: module:line.
|
||||
|
||||
=item * C<E<lt>numberE<gt>> E<mdash> stack dump depth (callee E<larr>
|
||||
caller). Default: 1.
|
||||
|
||||
=item * C<-E<lt>numberE<gt>> E<mdash> Inverse stack dump depth (caller
|
||||
E<rarr> callee).
|
||||
|
||||
=item * C<s> E<mdash> Split stack dump after first stack level. Implies
|
||||
depth E<ge> 2 or depth E<le> -2.
|
||||
|
||||
=item * C<p> E<mdash> Show full path for module names.
|
||||
|
||||
=item * C<v> E<mdash> Show VM states.
|
||||
|
||||
=item * C<z> E<mdash> Show zones.
|
||||
|
||||
=item * C<r> E<mdash> Show raw sample counts. Default: show
|
||||
percentages.
|
||||
|
||||
=item * C<a> E<mdash> Annotate excerpts from source code files.
|
||||
|
||||
=item * C<A> E<mdash> Annotate complete source code files.
|
||||
|
||||
=item * C<G> E<mdash> Produce raw output suitable for graphical tools.
|
||||
|
||||
=item * C<mE<lt>numberE<gt>> E<mdash> Minimum sample percentage to be
|
||||
shown. Default: 3%.
|
||||
|
||||
=item * C<iE<lt>numberE<gt>> E<mdash> Sampling interval in
|
||||
milliseconds. Default: 10ms.
|
||||
|
||||
Note: The actual sampling precision is OS-dependent.
|
||||
|
||||
=back
|
||||
|
||||
The default output for C<-jp> is a list of the most CPU consuming spots
|
||||
in the application. Increasing the stack dump depth with (say) C<-jp=2>
|
||||
may help to point out the main callers or callees of hotspots. But
|
||||
sample aggregation is still flat per unique stack dump.
|
||||
|
||||
To get a two-level view (split view) of callers/callees, use C<-jp=s>
|
||||
or C<-jp=-s>. The percentages shown for the second level are relative
|
||||
to the first level.
|
||||
|
||||
To see how much time is spent in each line relative to a function, use
|
||||
C<-jp=fl>.
|
||||
|
||||
To see how much time is spent in different VM states or zones, use
|
||||
C<-jp=v> or C<-jp=z>.
|
||||
|
||||
Combinations of C<v/z> with C<f/F/l> produce two-level views, e.g.
|
||||
C<-jp=vf> or C<-jp=fv>. This shows the time spent in a VM state or zone
|
||||
vs. hotspots. This can be used to answer questions like "Which time
|
||||
consuming functions are only interpreted?" or "What's the garbage
|
||||
collector overhead for a specific function?".
|
||||
|
||||
Multiple options can be combined E<mdash> but not all combinations make
|
||||
sense, see above. E.g. C<-jp=3si4m1> samples three stack levels deep in
|
||||
4ms intervals and shows a split view of the CPU consuming functions and
|
||||
their callers with a 1% threshold.
|
||||
|
||||
Source code annotations produced by C<-jp=a> or C<-jp=A> are always
|
||||
flat and at the line level. Obviously, the source code files need to be
|
||||
readable by the profiler script.
|
||||
|
||||
The high-level profiler can also be started and stopped from Lua code
|
||||
with:
|
||||
|
||||
require("jit.p").start(options, output)
|
||||
...
|
||||
require("jit.p").stop()
|
||||
|
||||
=head2 C<jit.zone> E<mdash> Zones
|
||||
|
||||
Zones can be used to provide information about different parts of an
|
||||
application to the high-level profiler. E.g. a game could make use of
|
||||
an C<"AI"> zone, a C<"PHYS"> zone, etc. Zones are hierarchical,
|
||||
organized as a stack.
|
||||
|
||||
The C<jit.zone> module needs to be loaded explicitly:
|
||||
|
||||
local zone = require("jit.zone")
|
||||
|
||||
=over
|
||||
|
||||
=item * C<zone("name")> pushes a named zone to the zone stack.
|
||||
|
||||
=item * C<zone()> pops the current zone from the zone stack and returns
|
||||
its name.
|
||||
|
||||
=item * C<zone:get()> returns the current zone name or C<nil>.
|
||||
|
||||
=item * C<zone:flush()> flushes the zone stack.
|
||||
|
||||
=back
|
||||
|
||||
To show the time spent in each zone use C<-jp=z>. To show the time
|
||||
spent relative to hotspots use e.g. C<-jp=zf> or C<-jp=fz>.
|
||||
|
||||
=head2 Low-level Lua API
|
||||
|
||||
The C<jit.profile> module gives access to the low-level API of the
|
||||
profiler from Lua code. This module needs to be loaded explicitly:
|
||||
|
||||
local profile = require("jit.profile")
|
||||
|
||||
This module can be used to implement your own higher-level profiler. A
|
||||
typical profiling run starts the profiler, captures stack dumps in the
|
||||
profiler callback, adds them to a hash table to aggregate the number of
|
||||
samples, stops the profiler and then analyzes all of the captured stack
|
||||
dumps. Other parameters can be sampled in the profiler callback, too.
|
||||
But it's important not to spend too much time in the callback, since
|
||||
this may skew the statistics.
|
||||
|
||||
=head2 C<profile.start(mode, cb)> E<mdash> Start profiler
|
||||
|
||||
This function starts the profiler. The C<mode> argument is a string
|
||||
holding options:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<f> E<mdash> Profile with precision down to the function
|
||||
level.
|
||||
|
||||
=item * C<l> E<mdash> Profile with precision down to the line level.
|
||||
|
||||
=item * C<iE<lt>numberE<gt>> E<mdash> Sampling interval in milliseconds
|
||||
(default 10ms). Note: The actual sampling precision is OS-dependent.
|
||||
|
||||
=back
|
||||
|
||||
The C<cb> argument is a callback function which is called with three
|
||||
arguments: C<(thread, samples, vmstate)>. The callback is called on a
|
||||
separate coroutine, the C<thread> argument is the state that holds the
|
||||
stack to sample for profiling. Note: do I<not> modify the stack of that
|
||||
state or call functions on it.
|
||||
|
||||
C<samples> gives the number of accumulated samples since the last
|
||||
callback (usually 1).
|
||||
|
||||
C<vmstate> holds the VM state at the time the profiling timer
|
||||
triggered. This may or may not correspond to the state of the VM when
|
||||
the profiling callback is called. The state is either C<'N'> native
|
||||
(compiled) code, C<'I'> interpreted code, C<'C'> C code, C<'G'> the
|
||||
garbage collector, or C<'J'> the JIT compiler.
|
||||
|
||||
=head2 C<profile.stop()> E<mdash> Stop profiler
|
||||
|
||||
This function stops the profiler.
|
||||
|
||||
=head2 C<dump = profile.dumpstack([thread,] fmt, depth)> E<mdash> Dump
|
||||
stack
|
||||
|
||||
This function allows taking stack dumps in an efficient manner. It
|
||||
returns a string with a stack dump for the C<thread> (coroutine),
|
||||
formatted according to the C<fmt> argument:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<p> E<mdash> Preserve the full path for module names.
|
||||
Otherwise only the file name is used.
|
||||
|
||||
=item * C<f> E<mdash> Dump the function name if it can be derived.
|
||||
Otherwise use module:line.
|
||||
|
||||
=item * C<F> E<mdash> Ditto, but dump module:name.
|
||||
|
||||
=item * C<l> E<mdash> Dump module:line.
|
||||
|
||||
=item * C<Z> E<mdash> Zap the following characters for the last dumped
|
||||
frame.
|
||||
|
||||
=item * All other characters are added verbatim to the output string.
|
||||
|
||||
=back
|
||||
|
||||
The C<depth> argument gives the number of frames to dump, starting at
|
||||
the topmost frame of the thread. A negative number dumps the frames in
|
||||
inverse order.
|
||||
|
||||
The first example prints a list of the current module names and line
|
||||
numbers of up to 10 frames in separate lines. The second example prints
|
||||
semicolon-separated function names for all frames (up to 100) in
|
||||
inverse order:
|
||||
|
||||
print(profile.dumpstack(thread, "l\n", 10))
|
||||
print(profile.dumpstack(thread, "lZ;", -100))
|
||||
|
||||
=head2 Low-level C API
|
||||
|
||||
The profiler can be controlled directly from C code, e.g. for use by
|
||||
IDEs. The declarations are in C<"luajit.h"> (see Lua/C API extensions).
|
||||
|
||||
=head2 C<luaJIT_profile_start(L, mode, cb, data)> E<mdash> Start
|
||||
profiler
|
||||
|
||||
This function starts the profiler. See above for a description of the
|
||||
C<mode> argument.
|
||||
|
||||
The C<cb> argument is a callback function with the following
|
||||
declaration:
|
||||
|
||||
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
|
||||
int samples, int vmstate);
|
||||
|
||||
C<data> is available for use by the callback. C<L> is the state that
|
||||
holds the stack to sample for profiling. Note: do I<not> modify this
|
||||
stack or call functions on this stack E<mdash> use a separate coroutine
|
||||
for this purpose. See above for a description of C<samples> and
|
||||
C<vmstate>.
|
||||
|
||||
=head2 C<luaJIT_profile_stop(L)> E<mdash> Stop profiler
|
||||
|
||||
This function stops the profiler.
|
||||
|
||||
=head2 C<p = luaJIT_profile_dumpstack(L, fmt, depth, len)> E<mdash>
|
||||
Dump stack
|
||||
|
||||
This function allows taking stack dumps in an efficient manner. See
|
||||
above for a description of C<fmt> and C<depth>.
|
||||
|
||||
This function returns a C<const char *> pointing to a private string
|
||||
buffer of the profiler. The C<int *len> argument returns the length of
|
||||
the output string. The buffer is overwritten on the next call and
|
||||
deallocated when the profiler stops. You either need to consume the
|
||||
content immediately or copy it for later use.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_profiler.html
|
||||
# 13135 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,477 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
|
||||
E<rchevron> standard Lua library functions and the full set of
|
||||
E<rchevron> Lua/C API functions.
|
||||
|
||||
LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
|
||||
loader level. This means you can compile a C module against the
|
||||
standard Lua headers and load the same shared library from either Lua
|
||||
or LuaJIT.
|
||||
|
||||
LuaJIT extends the standard Lua VM with new functionality and adds
|
||||
several extension modules. Please note this page is only about
|
||||
I<functional> enhancements and not about performance enhancements, such
|
||||
as the optimized VM, the faster interpreter or the JIT compiler.
|
||||
|
||||
=head2 Extensions Modules
|
||||
|
||||
LuaJIT comes with several built-in extension modules:
|
||||
|
||||
=head2 C<bit.*> E<mdash> Bitwise operations
|
||||
|
||||
LuaJIT supports all bitwise operations as defined by E<rchevron> Lua
|
||||
BitOp:
|
||||
|
||||
bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
|
||||
bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
|
||||
|
||||
This module is a LuaJIT built-in E<mdash> you don't need to download or
|
||||
install Lua BitOp. The Lua BitOp site has full documentation for all
|
||||
E<rchevron> Lua BitOp API functions. The FFI adds support for 64 bit
|
||||
bitwise operations, using the same API functions.
|
||||
|
||||
Please make sure to C<require> the module before using any of its
|
||||
functions:
|
||||
|
||||
local bit = require("bit")
|
||||
|
||||
An already installed Lua BitOp module is ignored by LuaJIT. This way
|
||||
you can use bit operations from both Lua and LuaJIT on a shared
|
||||
installation.
|
||||
|
||||
=head2 C<ffi.*> E<mdash> FFI library
|
||||
|
||||
The FFI library allows calling external C functions and the use of C
|
||||
data structures from pure Lua code.
|
||||
|
||||
=head2 C<jit.*> E<mdash> JIT compiler control
|
||||
|
||||
The functions in this module control the behavior of the JIT compiler
|
||||
engine.
|
||||
|
||||
=head2 C API extensions
|
||||
|
||||
LuaJIT adds some extra functions to the Lua/C API.
|
||||
|
||||
=head2 Profiler
|
||||
|
||||
LuaJIT has an integrated profiler.
|
||||
|
||||
=head2 Enhanced Standard Library Functions
|
||||
|
||||
=head2 C<xpcall(f, err [,args...])> passes arguments
|
||||
|
||||
Unlike the standard implementation in Lua 5.1, C<xpcall()> passes any
|
||||
arguments after the error function to the function which is called in a
|
||||
protected context.
|
||||
|
||||
=head2 C<loadfile()> etc. handle UTF-8 source code
|
||||
|
||||
Non-ASCII characters are handled transparently by the Lua source code
|
||||
parser. This allows the use of UTF-8 characters in identifiers and
|
||||
strings. A UTF-8 BOM is skipped at the start of the source code.
|
||||
|
||||
=head2 C<tostring()> etc. canonicalize NaN and E<plusmn>Inf
|
||||
|
||||
All number-to-string conversions consistently convert non-finite
|
||||
numbers to the same strings on all platforms. NaN results in C<"nan">,
|
||||
positive infinity results in C<"inf"> and negative infinity results in
|
||||
C<"-inf">.
|
||||
|
||||
=head2 C<tonumber()> etc. use builtin string to number conversion
|
||||
|
||||
All string-to-number conversions consistently convert integer and
|
||||
floating-point inputs in decimal, hexadecimal and binary on all
|
||||
platforms. C<strtod()> is I<not> used anymore, which avoids numerous
|
||||
problems with poor C library implementations. The builtin conversion
|
||||
function provides full precision according to the IEEE-754 standard, it
|
||||
works independently of the current locale and it supports hex
|
||||
floating-point numbers (e.g. C<0x1.5p-3>).
|
||||
|
||||
=head2 C<string.dump(f [,strip])> generates portable bytecode
|
||||
|
||||
An extra argument has been added to C<string.dump()>. If set to
|
||||
C<true>, 'stripped' bytecode without debug information is generated.
|
||||
This speeds up later bytecode loading and reduces memory usage. See
|
||||
also the C<-b> command line option.
|
||||
|
||||
The generated bytecode is portable and can be loaded on any
|
||||
architecture that LuaJIT supports, independent of word size or
|
||||
endianness. However the bytecode compatibility versions must match.
|
||||
Bytecode stays compatible for dot releases (x.y.0 E<rarr> x.y.1), but
|
||||
may change with major or minor releases (2.0 E<rarr> 2.1) or between
|
||||
any beta release. Foreign bytecode (e.g. from Lua 5.1) is incompatible
|
||||
and cannot be loaded.
|
||||
|
||||
Note: C<LJ_GC64> mode requires a different frame layout, which implies
|
||||
a different, incompatible bytecode format for ports that use this mode
|
||||
(e.g. ARM64 or MIPS64) or when explicitly enabled for x64. This may be
|
||||
rectified in the future.
|
||||
|
||||
=head2 C<table.new(narray, nhash)> allocates a pre-sized table
|
||||
|
||||
An extra library function C<table.new()> can be made available via
|
||||
C<require("table.new")>. This creates a pre-sized table, just like the
|
||||
C API equivalent C<lua_createtable()>. This is useful for big tables if
|
||||
the final table size is known and automatic table resizing is too
|
||||
expensive.
|
||||
|
||||
=head2 C<table.clear(tab)> clears a table
|
||||
|
||||
An extra library function C<table.clear()> can be made available via
|
||||
C<require("table.clear")>. This clears all keys and values from a
|
||||
table, but preserves the allocated array/hash sizes. This is useful
|
||||
when a table, which is linked from multiple places, needs to be cleared
|
||||
and/or when recycling a table for use by the same context. This avoids
|
||||
managing backlinks, saves an allocation and the overhead of incremental
|
||||
array/hash part growth.
|
||||
|
||||
Please note this function is meant for very specific situations. In
|
||||
most cases it's better to replace the (usually single) link with a new
|
||||
table and let the GC do its work.
|
||||
|
||||
=head2 Enhanced PRNG for C<math.random()>
|
||||
|
||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||
C<math.random()> and C<math.randomseed()>. The quality of the PRNG
|
||||
results is much superior compared to the standard Lua implementation
|
||||
which uses the platform-specific ANSI rand().
|
||||
|
||||
The PRNG generates the same sequences from the same seeds on all
|
||||
platforms and makes use of all bits in the seed argument.
|
||||
C<math.random()> without arguments generates 52 pseudo-random bits for
|
||||
every call. The result is uniformly distributed between 0.0 and 1.0.
|
||||
It's correctly scaled up and rounded for C<math.random(n [,m])> to
|
||||
preserve uniformity.
|
||||
|
||||
=head2 C<io.*> functions handle 64 bit file offsets
|
||||
|
||||
The file I/O functions in the standard C<io.*> library handle 64 bit
|
||||
file offsets. In particular this means it's possible to open files
|
||||
larger than 2 Gigabytes and to reposition or obtain the current file
|
||||
position for offsets beyond 2 GB (C<fp:seek()> method).
|
||||
|
||||
=head2 C<debug.*> functions identify metamethods
|
||||
|
||||
C<debug.getinfo()> and C<lua_getinfo()> also return information about
|
||||
invoked metamethods. The C<namewhat> field is set to C<"metamethod">
|
||||
and the C<name> field has the name of the corresponding metamethod
|
||||
(e.g. C<"__index">).
|
||||
|
||||
=head2 Fully Resumable VM
|
||||
|
||||
The LuaJIT VM is fully resumable. This means you can yield from a
|
||||
coroutine even across contexts, where this would not possible with the
|
||||
standard Lua 5.1 VM: e.g. you can yield across C<pcall()> and
|
||||
C<xpcall()>, across iterators and across metamethods.
|
||||
|
||||
=head2 Extensions from Lua 5.2
|
||||
|
||||
LuaJIT supports some language and library extensions from Lua 5.2.
|
||||
Features that are unlikely to break existing code are unconditionally
|
||||
enabled:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<goto> and C<::labels::>.
|
||||
|
||||
=item * Hex escapes C<'\x3F'> and C<'\*'> escape in strings.
|
||||
|
||||
=item * C<load(string|reader [, chunkname [,mode [,env]]])>.
|
||||
|
||||
=item * C<loadstring()> is an alias for C<load()>.
|
||||
|
||||
=item * C<loadfile(filename [,mode [,env]])>.
|
||||
|
||||
=item * C<math.log(x [,base])>.
|
||||
|
||||
=item * C<string.rep(s, n [,sep])>.
|
||||
|
||||
=item * C<string.format()>: C<%q> reversible. C<%s> checks
|
||||
C<__tostring>. C<%a> and C<"%A> added.
|
||||
|
||||
=item * String matching pattern C<%g> added.
|
||||
|
||||
=item * C<io.read("*L")>.
|
||||
|
||||
=item * C<io.lines()> and C<file:lines()> process C<io.read()> options.
|
||||
|
||||
=item * C<os.exit(status|true|false [,close])>.
|
||||
|
||||
=item * C<package.searchpath(name, path [, sep [, rep]])>.
|
||||
|
||||
=item * C<package.loadlib(name, "*")>.
|
||||
|
||||
=item * C<debug.getinfo()> returns C<nparams> and C<isvararg> for
|
||||
option C<"u">.
|
||||
|
||||
=item * C<debug.getlocal()> accepts function instead of level.
|
||||
|
||||
=item * C<debug.getlocal()> and C<debug.setlocal()> accept negative
|
||||
indexes for varargs.
|
||||
|
||||
=item * C<debug.getupvalue()> and C<debug.setupvalue()> handle C
|
||||
functions.
|
||||
|
||||
=item * C<debug.upvalueid()> and C<debug.upvaluejoin()>.
|
||||
|
||||
=item * Lua/C API extensions: C<lua_version()> C<lua_upvalueid()>
|
||||
C<lua_upvaluejoin()> C<lua_loadx()> C<lua_copy()> C<lua_tonumberx()>
|
||||
C<lua_tointegerx()> C<luaL_fileresult()> C<luaL_execresult()>
|
||||
C<luaL_loadfilex()> C<luaL_loadbufferx()> C<luaL_traceback()>
|
||||
C<luaL_setfuncs()> C<luaL_pushmodule()> C<luaL_newlibtable()>
|
||||
C<luaL_newlib()> C<luaL_testudata()> C<luaL_setmetatable()>
|
||||
|
||||
=item * Command line option C<-E>.
|
||||
|
||||
=item * Command line checks C<__tostring> for errors.
|
||||
|
||||
=back
|
||||
|
||||
Other features are only enabled, if LuaJIT is built with
|
||||
C<-DLUAJIT_ENABLE_LUA52COMPAT>:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<goto> is a keyword and not a valid variable name anymore.
|
||||
|
||||
=item * C<break> can be placed anywhere. Empty statements (C<;;>) are
|
||||
allowed.
|
||||
|
||||
=item * C<__lt>, C<__le> are invoked for mixed types.
|
||||
|
||||
=item * C<__len> for tables. C<rawlen()> library function.
|
||||
|
||||
=item * C<pairs()> and C<ipairs()> check for C<__pairs> and
|
||||
C<__ipairs>.
|
||||
|
||||
=item * C<coroutine.running()> returns two results.
|
||||
|
||||
=item * C<table.pack()> and C<table.unpack()> (same as C<unpack()>).
|
||||
|
||||
=item * C<io.write()> and C<file:write()> return file handle instead of
|
||||
C<true>.
|
||||
|
||||
=item * C<os.execute()> and C<pipe:close()> return detailed exit
|
||||
status.
|
||||
|
||||
=item * C<debug.setmetatable()> returns object.
|
||||
|
||||
=item * C<debug.getuservalue()> and C<debug.setuservalue()>.
|
||||
|
||||
=item * Remove C<math.mod()>, C<string.gfind()>.
|
||||
|
||||
=item * C<package.searchers>.
|
||||
|
||||
=item * C<module()> returns the module table.
|
||||
|
||||
=back
|
||||
|
||||
Note: this provides only partial compatibility with Lua 5.2 at the
|
||||
language and Lua library level. LuaJIT is API+ABI-compatible with Lua
|
||||
5.1, which prevents implementing features that would otherwise break
|
||||
the Lua/C API and ABI (e.g. C<_ENV>).
|
||||
|
||||
=head2 Extensions from Lua 5.3
|
||||
|
||||
LuaJIT supports some extensions from Lua 5.3:
|
||||
|
||||
=over
|
||||
|
||||
=item * Unicode escape C<'\u{XX...}'> embeds the UTF-8 encoding in
|
||||
string literals.
|
||||
|
||||
=item * The argument table C<arg> can be read (and modified) by
|
||||
C<LUA_INIT> and C<-e> chunks.
|
||||
|
||||
=item * C<io.read()> and C<file:read()> accept formats with or without
|
||||
a leading C<*>.
|
||||
|
||||
=item * C<table.move(a1, f, e, t [,a2])>.
|
||||
|
||||
=item * C<coroutine.isyieldable()>.
|
||||
|
||||
=item * Lua/C API extensions: C<lua_isyieldable()>
|
||||
|
||||
=back
|
||||
|
||||
=head2 C++ Exception Interoperability
|
||||
|
||||
LuaJIT has built-in support for interoperating with C++ exceptions. The
|
||||
available range of features depends on the target platform and the
|
||||
toolchain used to compile LuaJIT:
|
||||
|
||||
Platform
|
||||
|
||||
Compiler
|
||||
|
||||
Interoperability
|
||||
|
||||
POSIX/x64, DWARF2 unwinding
|
||||
|
||||
GCC 4.3+, Clang
|
||||
|
||||
B<Full>
|
||||
|
||||
ARM C<-DLUAJIT_UNWIND_EXTERNAL>
|
||||
|
||||
GCC, Clang
|
||||
|
||||
B<Full>
|
||||
|
||||
Other platforms, DWARF2 unwinding
|
||||
|
||||
GCC, Clang
|
||||
|
||||
B<Limited>
|
||||
|
||||
Windows/x64
|
||||
|
||||
MSVC or WinSDK
|
||||
|
||||
B<Full>
|
||||
|
||||
Windows/x86
|
||||
|
||||
Any
|
||||
|
||||
B<Full>
|
||||
|
||||
Other platforms
|
||||
|
||||
Other compilers
|
||||
|
||||
B<No>
|
||||
|
||||
B<Full interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * C++ exceptions can be caught on the Lua side with C<pcall()>,
|
||||
C<lua_pcall()> etc.
|
||||
|
||||
=item * C++ exceptions will be converted to the generic Lua error
|
||||
C<"C++ exception">, unless you use the C call wrapper feature.
|
||||
|
||||
=item * It's safe to throw C++ exceptions across non-protected Lua
|
||||
frames on the C stack. The contents of the C++ exception object pass
|
||||
through unmodified.
|
||||
|
||||
=item * Lua errors can be caught on the C++ side with C<catch(...)>.
|
||||
The corresponding Lua error message can be retrieved from the Lua
|
||||
stack.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames is safe. C++ destructors
|
||||
will be called.
|
||||
|
||||
=back
|
||||
|
||||
B<Limited interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * C++ exceptions can be caught on the Lua side with C<pcall()>,
|
||||
C<lua_pcall()> etc.
|
||||
|
||||
=item * C++ exceptions will be converted to the generic Lua error
|
||||
C<"C++ exception">, unless you use the C call wrapper feature.
|
||||
|
||||
=item * C++ exceptions will be caught by non-protected Lua frames and
|
||||
are rethrown as a generic Lua error. The C++ exception object will be
|
||||
destroyed.
|
||||
|
||||
=item * Lua errors B<cannot> be caught on the C++ side.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames will B<not> call C++
|
||||
destructors.
|
||||
|
||||
=back
|
||||
|
||||
B<No interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * It's B<not> safe to throw C++ exceptions across Lua frames.
|
||||
|
||||
=item * C++ exceptions B<cannot> be caught on the Lua side.
|
||||
|
||||
=item * Lua errors B<cannot> be caught on the C++ side.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames will B<not> call C++
|
||||
destructors.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file extensions.html
|
||||
# 17733 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,224 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Frequently Asked Questions (FAQ)
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Where can I learn more about LuaJIT and Lua?
|
||||
|
||||
=over
|
||||
|
||||
=item * The E<rchevron> LuaJIT mailing list focuses on topics related
|
||||
to LuaJIT.
|
||||
|
||||
=item * The E<rchevron> LuaJIT wiki gathers community resources about
|
||||
LuaJIT.
|
||||
|
||||
=item * News about Lua itself can be found at the E<rchevron> Lua
|
||||
mailing list. The mailing list archives are worth checking out for
|
||||
older postings about LuaJIT.
|
||||
|
||||
=item * The E<rchevron> main Lua.org site has complete E<rchevron>
|
||||
documentation of the language and links to books and papers about Lua.
|
||||
|
||||
=item * The community-managed E<rchevron> Lua Wiki has information
|
||||
about diverse topics.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Where can I learn more about the compiler technology used by
|
||||
LuaJIT?
|
||||
|
||||
I'm planning to write more documentation about the internals of LuaJIT.
|
||||
In the meantime, please use the following Google Scholar searches to
|
||||
find relevant papers:
|
||||
|
||||
Search for: E<rchevron> Trace Compiler
|
||||
|
||||
Search for: E<rchevron> JIT Compiler
|
||||
|
||||
Search for: E<rchevron> Dynamic Language Optimizations
|
||||
|
||||
Search for: E<rchevron> SSA Form
|
||||
|
||||
Search for: E<rchevron> Linear Scan Register Allocation
|
||||
|
||||
Here is a list of the E<rchevron> innovative features in LuaJIT.
|
||||
|
||||
And, you know, reading the source is of course the only way to
|
||||
enlightenment. :-)
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why do I get this error: "attempt to index global 'arg' (a nil
|
||||
value)"?
|
||||
|
||||
Q: My vararg functions fail after switching to LuaJIT!
|
||||
|
||||
LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
|
||||
support the implicit C<arg> parameter for old-style vararg functions
|
||||
from Lua 5.0.
|
||||
|
||||
Please convert your code to the E<rchevron> Lua 5.1 vararg syntax.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why do I get this error: "bad FPU precision"?
|
||||
|
||||
=item Q: I get weird behavior after initializing Direct3D.
|
||||
|
||||
=item Q: Some FPU operations crash after I load a Delphi DLL.
|
||||
|
||||
DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
|
||||
mode by default. This violates the Windows ABI and interferes with the
|
||||
operation of many programs E<mdash> LuaJIT is affected, too. Please
|
||||
make sure you always use the C<D3DCREATE_FPU_PRESERVE> flag when
|
||||
initializing Direct3D.
|
||||
|
||||
Direct3D version 10 or higher do not show this behavior anymore.
|
||||
Consider testing your application with older versions, too.
|
||||
|
||||
Similarly, the Borland/Delphi runtime modifies the FPU control word and
|
||||
enables FP exceptions. Of course this violates the Windows ABI, too.
|
||||
Please check the Delphi docs for the Set8087CW method.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Sometimes Ctrl-C fails to stop my Lua program. Why?
|
||||
|
||||
The interrupt signal handler sets a Lua debug hook. But this is
|
||||
currently ignored by compiled code (this will eventually be fixed). If
|
||||
your program is running in a tight loop and never falls back to the
|
||||
interpreter, the debug hook never runs and can't throw the
|
||||
"interrupted!" error.
|
||||
|
||||
In the meantime you have to press Ctrl-C twice to get stop your
|
||||
program. That's similar to when it's stuck running inside a C function
|
||||
under the Lua interpreter.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why doesn't my favorite power-patch for Lua apply against
|
||||
LuaJIT?
|
||||
|
||||
Because it's a completely redesigned VM and has very little code in
|
||||
common with Lua anymore. Also, if the patch introduces changes to the
|
||||
Lua semantics, these would need to be reflected everywhere in the VM,
|
||||
from the interpreter up to all stages of the compiler.
|
||||
|
||||
Please use only standard Lua language constructs. For many common needs
|
||||
you can use source transformations or use wrapper or proxy functions.
|
||||
The compiler will happily optimize away such indirections.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?
|
||||
|
||||
Because it's a compiler E<mdash> it needs to generate native machine
|
||||
code. This means the code generator must be ported to each
|
||||
architecture. And the fast interpreter is written in assembler and must
|
||||
be ported, too. This is quite an undertaking.
|
||||
|
||||
The install documentation shows the supported architectures. Other
|
||||
architectures will follow based on sufficient user demand and/or
|
||||
sponsoring.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: When will feature X be added? When will the next version be
|
||||
released?
|
||||
|
||||
When it's ready.
|
||||
|
||||
C'mon, it's open source E<mdash> I'm doing it on my own time and you're
|
||||
getting it for free. You can either contribute a patch or sponsor the
|
||||
development of certain features, if they are important to you.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file faq.html
|
||||
# 7685 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,700 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Installation
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is only distributed as a source package. This page explains how
|
||||
to build and install LuaJIT with different operating systems and C
|
||||
compilers.
|
||||
|
||||
For the impatient (on POSIX systems):
|
||||
|
||||
make && sudo make install
|
||||
|
||||
LuaJIT currently builds out-of-the box on most systems. Here's the
|
||||
compatibility matrix for the supported combinations of operating
|
||||
systems, CPUs and compilers:
|
||||
|
||||
CPU / OS
|
||||
|
||||
Linux or
|
||||
|
||||
Android
|
||||
|
||||
*BSD, Other
|
||||
|
||||
OSX 10.4+ or
|
||||
|
||||
iOS 3.0+
|
||||
|
||||
Windows
|
||||
|
||||
XP/Vista/7
|
||||
|
||||
x86 (32 bit)
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
MSVC, MSVC/EE
|
||||
|
||||
WinSDK
|
||||
|
||||
MinGW, Cygwin
|
||||
|
||||
x64 (64 bit)
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
ORBIS (PS4)
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
MSVC + SDK v7.0
|
||||
|
||||
WinSDK v7.0
|
||||
|
||||
Durango (Xbox One)
|
||||
|
||||
ARMv5+
|
||||
|
||||
ARM9E+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
PSP2 (PS VITA)
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
ARM64
|
||||
|
||||
GCC 4.8+
|
||||
|
||||
XCode 6.0+
|
||||
|
||||
Clang 3.5+
|
||||
|
||||
PPC
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.1 (PS3)
|
||||
|
||||
XEDK (Xbox 360)
|
||||
|
||||
MIPS32
|
||||
|
||||
MIPS64
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
=head2 Configuring LuaJIT
|
||||
|
||||
The standard configuration should work fine for most installations.
|
||||
Usually there is no need to tweak the settings. The following files
|
||||
hold all user-configurable settings:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<src/luaconf.h> sets some configuration variables.
|
||||
|
||||
=item * C<Makefile> has settings for B<installing> LuaJIT (POSIX only).
|
||||
|
||||
=item * C<src/Makefile> has settings for B<compiling> LuaJIT under
|
||||
POSIX, MinGW or Cygwin.
|
||||
|
||||
=item * C<src/msvcbuild.bat> has settings for compiling LuaJIT with
|
||||
MSVC or WinSDK.
|
||||
|
||||
=back
|
||||
|
||||
Please read the instructions given in these files, before changing any
|
||||
settings.
|
||||
|
||||
LuaJIT on x64 currently uses 32 bit GC objects by default. C<LJ_GC64>
|
||||
mode may be explicitly enabled: add C<XCFLAGS=-DLUAJIT_ENABLE_GC64> to
|
||||
the make command or run C<msvcbuild gc64> for MSVC/WinSDK. Please check
|
||||
the note about the bytecode format differences, too.
|
||||
|
||||
=head2 POSIX Systems (Linux, OSX, *BSD etc.)
|
||||
|
||||
=head2 Prerequisites
|
||||
|
||||
Depending on your distribution, you may need to install a package for
|
||||
GCC, the development headers and/or a complete SDK. E.g. on a current
|
||||
Debian/Ubuntu, install C<libc6-dev> with the package manager.
|
||||
|
||||
Download the current source package of LuaJIT (pick the .tar.gz), if
|
||||
you haven't already done so. Move it to a directory of your choice,
|
||||
open a terminal window and change to this directory. Now unpack the
|
||||
archive and change to the newly created directory:
|
||||
|
||||
tar zxf LuaJIT-2.0.5.tar.gz
|
||||
cd LuaJIT-2.0.5
|
||||
|
||||
=head2 Building LuaJIT
|
||||
|
||||
The supplied Makefiles try to auto-detect the settings needed for your
|
||||
operating system and your compiler. They need to be run with GNU Make,
|
||||
which is probably the default on your system, anyway. Simply run:
|
||||
|
||||
make
|
||||
|
||||
This always builds a native binary, depending on the host OS you're
|
||||
running this command on. Check the section on cross-compilation for
|
||||
more options.
|
||||
|
||||
By default, modules are only searched under the prefix C</usr/local>.
|
||||
You can add an extra prefix to the search paths by appending the
|
||||
C<PREFIX> option, e.g.:
|
||||
|
||||
make PREFIX=/home/myself/lj2
|
||||
|
||||
Note for OSX: if the C<MACOSX_DEPLOYMENT_TARGET> environment variable
|
||||
is not set, then it's forced to C<10.4>.
|
||||
|
||||
=head2 Installing LuaJIT
|
||||
|
||||
The top-level Makefile installs LuaJIT by default under C</usr/local>,
|
||||
i.e. the executable ends up in C</usr/local/bin> and so on. You need
|
||||
root privileges to write to this path. So, assuming sudo is installed
|
||||
on your system, run the following command and enter your sudo password:
|
||||
|
||||
sudo make install
|
||||
|
||||
Otherwise specify the directory prefix as an absolute path, e.g.:
|
||||
|
||||
make install PREFIX=/home/myself/lj2
|
||||
|
||||
Obviously the prefixes given during build and installation need to be
|
||||
the same.
|
||||
|
||||
=head2 Windows Systems
|
||||
|
||||
=head2 Prerequisites
|
||||
|
||||
Either install one of the open source SDKs (E<rchevron> MinGW or
|
||||
E<rchevron> Cygwin), which come with a modified GCC plus the required
|
||||
development headers.
|
||||
|
||||
Or install Microsoft's Visual C++ (MSVC). The freely downloadable
|
||||
E<rchevron> Express Edition works just fine, but only contains an x86
|
||||
compiler.
|
||||
|
||||
The freely downloadable E<rchevron> Windows SDK only comes with command
|
||||
line tools, but this is all you need to build LuaJIT. It contains x86
|
||||
and x64 compilers.
|
||||
|
||||
Next, download the source package and unpack it using an archive
|
||||
manager (e.g. the Windows Explorer) to a directory of your choice.
|
||||
|
||||
=head2 Building with MSVC
|
||||
|
||||
Open a "Visual Studio .NET Command Prompt", C<cd> to the directory
|
||||
where you've unpacked the sources and run these commands:
|
||||
|
||||
cd src
|
||||
msvcbuild
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Building with the Windows SDK
|
||||
|
||||
Open a "Windows SDK Command Shell" and select the x86 compiler:
|
||||
|
||||
setenv /release /x86
|
||||
|
||||
Or select the x64 compiler:
|
||||
|
||||
setenv /release /x64
|
||||
|
||||
Then C<cd> to the directory where you've unpacked the sources and run
|
||||
these commands:
|
||||
|
||||
cd src
|
||||
msvcbuild
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Building with MinGW or Cygwin
|
||||
|
||||
Open a command prompt window and make sure the MinGW or Cygwin programs
|
||||
are in your path. Then C<cd> to the directory where you've unpacked the
|
||||
sources and run this command for MinGW:
|
||||
|
||||
mingw32-make
|
||||
|
||||
Or this command for Cygwin:
|
||||
|
||||
make
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Installing LuaJIT
|
||||
|
||||
Copy C<luajit.exe> and C<lua51.dll> (built in the C<src> directory) to
|
||||
a newly created directory (any location is ok). Add C<lua> and
|
||||
C<lua\jit> directories below it and copy all Lua files from the
|
||||
C<src\jit> directory of the distribution to the latter directory.
|
||||
|
||||
There are no hardcoded absolute path names E<mdash> all modules are
|
||||
loaded relative to the directory where C<luajit.exe> is installed (see
|
||||
C<src/luaconf.h>).
|
||||
|
||||
=head2 Cross-compiling LuaJIT
|
||||
|
||||
First, let's clear up some terminology:
|
||||
|
||||
=over
|
||||
|
||||
=item * Host: This is your development system, usually based on a x64
|
||||
or x86 CPU.
|
||||
|
||||
=item * Target: This is the target system you want LuaJIT to run on,
|
||||
e.g. Android/ARM.
|
||||
|
||||
=item * Toolchain: This comprises a C compiler, linker, assembler and a
|
||||
matching C library.
|
||||
|
||||
=item * Host (or system) toolchain: This is the toolchain used to build
|
||||
native binaries for your host system.
|
||||
|
||||
=item * Cross-compile toolchain: This is the toolchain used to build
|
||||
binaries for the target system. They can only be run on the target
|
||||
system.
|
||||
|
||||
=back
|
||||
|
||||
The GNU Makefile-based build system allows cross-compiling on any host
|
||||
for any supported target:
|
||||
|
||||
=over
|
||||
|
||||
=item * Yes, you need a toolchain for both your host I<and> your
|
||||
target!
|
||||
|
||||
=item * Both host and target architectures must have the same pointer
|
||||
size.
|
||||
|
||||
=item * E.g. if you want to cross-compile to a 32 bit target on a 64
|
||||
bit host, you need to install the multilib development package (e.g.
|
||||
C<libc6-dev-i386> on Debian/Ubuntu) and build a 32 bit host part
|
||||
(C<HOST_CC="gcc -m32">).
|
||||
|
||||
=item * 64 bit targets always require compilation on a 64 bit host.
|
||||
|
||||
=back
|
||||
|
||||
You need to specify C<TARGET_SYS> whenever the host OS and the target
|
||||
OS differ, or you'll get assembler or linker errors:
|
||||
|
||||
=over
|
||||
|
||||
=item * E.g. if you're compiling on a Windows or OSX host for embedded
|
||||
Linux or Android, you need to add C<TARGET_SYS=Linux> to the examples
|
||||
below.
|
||||
|
||||
=item * For a minimal target OS, you may need to disable the built-in
|
||||
allocator in C<src/Makefile> and use C<TARGET_SYS=Other>.
|
||||
|
||||
=item * Don't forget to specify the same C<TARGET_SYS> for the install
|
||||
step, too.
|
||||
|
||||
=back
|
||||
|
||||
Here are some examples where host and target have the same CPU:
|
||||
|
||||
# Cross-compile to a 32 bit binary on a multilib x64 OS
|
||||
make CC="gcc -m32"
|
||||
|
||||
# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)
|
||||
make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
|
||||
|
||||
The C<CROSS> prefix allows specifying a standard GNU cross-compile
|
||||
toolchain (Binutils, GCC and a matching libc). The prefix may vary
|
||||
depending on the C<--target> the toolchain was built for (note the
|
||||
C<CROSS> prefix has a trailing C<"-">). The examples below use the
|
||||
canonical toolchain triplets for Linux.
|
||||
|
||||
Since there's often no easy way to detect CPU features at runtime, it's
|
||||
important to compile with the proper CPU or architecture settings:
|
||||
|
||||
=over
|
||||
|
||||
=item * The best way to get consistent results is to specify the
|
||||
correct settings when building the toolchain yourself.
|
||||
|
||||
=item * For a pre-built, generic toolchain add C<-mcpu=...> or
|
||||
C<-march=...> and other necessary flags to C<TARGET_CFLAGS>.
|
||||
|
||||
=item * For ARM it's important to have the correct C<-mfloat-abi=...>
|
||||
setting, too. Otherwise LuaJIT may not run at the full performance of
|
||||
your target CPU.
|
||||
|
||||
=item * For MIPS it's important to select a supported ABI (o32 on
|
||||
MIPS32, n64 on MIPS64) and consistently compile your project either
|
||||
with hard-float or soft-float compiler settings.
|
||||
|
||||
=back
|
||||
|
||||
Here are some examples for targets with a different CPU than the host:
|
||||
|
||||
# ARM soft-float
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mfloat-abi=soft"
|
||||
|
||||
# ARM soft-float ABI with VFP (example for Cortex-A9)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
|
||||
|
||||
# ARM hard-float ABI with VFP (armhf, most modern toolchains)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
|
||||
|
||||
# ARM64
|
||||
make CROSS=aarch64-linux-
|
||||
|
||||
# PPC
|
||||
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
|
||||
|
||||
# MIPS32 big-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mips-linux-
|
||||
# MIPS32 little-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mipsel-linux-
|
||||
|
||||
# MIPS64 big-endian
|
||||
make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
# MIPS64 little-endian
|
||||
make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
|
||||
You can cross-compile for B<Android> using the Android NDK. The
|
||||
environment variables need to match the install locations and the
|
||||
desired target platform. E.g. Android 4.0 corresponds to ABI level 14.
|
||||
For details check the folder C<docs> in the NDK directory.
|
||||
|
||||
Only a few common variations for the different CPUs, ABIs and platforms
|
||||
are listed. Please use your own judgement for which combination you
|
||||
want to build/deploy or which lowest common denominator you want to
|
||||
pick:
|
||||
|
||||
# Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=8
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF $NDKARCH"
|
||||
|
||||
# Android/MIPS, mipsel (MIPS32R1 hard-float), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/mipsel-linux-android-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/mipsel-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-mips"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/x86-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/i686-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
You can cross-compile for B<iOS 3.0+> (iPhone/iPad) using the
|
||||
E<rchevron> iOS SDK:
|
||||
|
||||
Note: B<the JIT compiler is disabled for iOS>, because regular iOS Apps
|
||||
are not allowed to generate code at runtime. You'll only get the
|
||||
performance of the LuaJIT interpreter on iOS. This is still faster than
|
||||
plain Lua, but much slower than the JIT compiler. Please complain to
|
||||
Apple, not me. Or use Android. :-p
|
||||
|
||||
# iOS/ARM (32 bit)
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch armv7 -isysroot $ISDKP"
|
||||
make DEFAULT_CC=clang HOST_CC="clang -m32 -arch i386" \
|
||||
CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
|
||||
# iOS/ARM64
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch arm64 -isysroot $ISDKP"
|
||||
make DEFAULT_CC=clang CROSS="$(dirname $ICC)/" \
|
||||
TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
|
||||
=head2 Cross-compiling for consoles
|
||||
|
||||
Building LuaJIT for consoles requires both a supported host compiler
|
||||
(x86 or x64) and a cross-compiler (to PPC or ARM) from the official
|
||||
console SDK.
|
||||
|
||||
Due to restrictions on consoles, the JIT compiler is disabled and only
|
||||
the fast interpreter is built. This is still faster than plain Lua, but
|
||||
much slower than the JIT compiler. The FFI is disabled, too, since it's
|
||||
not very useful in such an environment.
|
||||
|
||||
The following commands build a static library C<libluajit.a>, which can
|
||||
be linked against your game, just like the Lua library.
|
||||
|
||||
To cross-compile for B<PS3> from a Linux host (requires 32 bit GCC,
|
||||
i.e. multilib Linux/x64) or a Windows host (requires 32 bit MinGW), run
|
||||
this command:
|
||||
|
||||
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
|
||||
|
||||
To cross-compile for B<PS4> from a Windows host, open a "Visual Studio
|
||||
.NET Command Prompt" (64 bit host compiler), C<cd> to the directory
|
||||
where you've unpacked the sources and run the following commands:
|
||||
|
||||
cd src
|
||||
ps4build
|
||||
|
||||
To cross-compile for B<PS Vita> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (32 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
psvitabuild
|
||||
|
||||
To cross-compile for B<Xbox 360> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (32 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
xedkbuild
|
||||
|
||||
To cross-compile for B<Xbox One> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (64 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
xb1build
|
||||
|
||||
=head2 Embedding LuaJIT
|
||||
|
||||
LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
|
||||
into your application, you probably don't need to do anything to switch
|
||||
to LuaJIT, except link with a different library:
|
||||
|
||||
=over
|
||||
|
||||
=item * It's strongly suggested to build LuaJIT separately using the
|
||||
supplied build system. Please do I<not> attempt to integrate the
|
||||
individual source files into your build tree. You'll most likely get
|
||||
the internal build dependencies wrong or mess up the compiler flags.
|
||||
Treat LuaJIT like any other external library and link your application
|
||||
with either the dynamic or static library, depending on your needs.
|
||||
|
||||
=item * If you want to load C modules compiled for plain Lua with
|
||||
C<require()>, you need to make sure the public symbols (e.g.
|
||||
C<lua_pushnumber>) are exported, too:
|
||||
|
||||
=over
|
||||
|
||||
=item * On POSIX systems you can either link to the shared library or
|
||||
link the static library into your application. In the latter case
|
||||
you'll need to export all public symbols from your main executable
|
||||
(e.g. C<-Wl,-E> on Linux) and add the external dependencies (e.g. C<-lm
|
||||
-ldl> on Linux).
|
||||
|
||||
=item * Since Windows symbols are bound to a specific DLL name, you
|
||||
need to link to the C<lua51.dll> created by the LuaJIT build (do not
|
||||
rename the DLL). You may link LuaJIT statically on Windows only if you
|
||||
don't intend to load Lua/C modules at runtime.
|
||||
|
||||
=back
|
||||
|
||||
=item * If you're building a 64 bit application on OSX which links
|
||||
directly or indirectly against LuaJIT which is not built for C<LJ_GC64>
|
||||
mode, you need to link your main executable with these flags:
|
||||
|
||||
-pagezero_size 10000 -image_base 100000000
|
||||
|
||||
=back
|
||||
|
||||
Additional hints for initializing LuaJIT using the C API functions:
|
||||
|
||||
=over
|
||||
|
||||
=item * Here's a E<rchevron> simple example for embedding Lua or LuaJIT
|
||||
into your application.
|
||||
|
||||
=item * Make sure you use C<luaL_newstate>. Avoid using
|
||||
C<lua_newstate>, since this uses the (slower) default memory allocator
|
||||
from your system (no support for this on x64).
|
||||
|
||||
=item * Make sure you use C<luaL_openlibs> and not the old Lua 5.0
|
||||
style of calling C<luaopen_base> etc. directly.
|
||||
|
||||
=item * To change or extend the list of standard libraries to load,
|
||||
copy C<src/lib_init.c> to your project and modify it accordingly. Make
|
||||
sure the C<jit> library is loaded or the JIT compiler will not be
|
||||
activated.
|
||||
|
||||
=item * The C<bit.*> module for bitwise operations is already built-in.
|
||||
There's no need to statically link E<rchevron> Lua BitOp to your
|
||||
application.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Hints for Distribution Maintainers
|
||||
|
||||
The LuaJIT build system has extra provisions for the needs of most
|
||||
POSIX-based distributions. If you're a package maintainer for a
|
||||
distribution, I<please> make use of these features and avoid patching,
|
||||
subverting, autotoolizing or messing up the build system in unspeakable
|
||||
ways.
|
||||
|
||||
There should be absolutely no need to patch C<luaconf.h> or any of the
|
||||
Makefiles. And please do not hand-pick files for your packages E<mdash>
|
||||
simply use whatever C<make install> creates. There's a reason for all
|
||||
of the files I<and> directories it creates.
|
||||
|
||||
The build system uses GNU make and auto-detects most settings based on
|
||||
the host you're building it on. This should work fine for native
|
||||
builds, even when sandboxed. You may need to pass some of the following
|
||||
flags to I<both> the C<make> and the C<make install> command lines for
|
||||
a regular distribution build:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<PREFIX> overrides the installation path and should usually be
|
||||
set to C</usr>. Setting this also changes the module paths and the
|
||||
paths needed to locate the shared library.
|
||||
|
||||
=item * C<DESTDIR> is an absolute path which allows you to install to a
|
||||
shadow tree instead of the root tree of the build system.
|
||||
|
||||
=item * C<MULTILIB> sets the architecture-specific library path
|
||||
component for multilib systems. The default is C<lib>.
|
||||
|
||||
=item * Have a look at the top-level C<Makefile> and C<src/Makefile>
|
||||
for additional variables to tweak. The following variables I<may> be
|
||||
overridden, but it's I<not> recommended, except for special needs like
|
||||
cross-builds: C<BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS,
|
||||
HOST_CFLAGS, TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS,
|
||||
TARGET_SHLDFLAGS, TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS,
|
||||
HOST_SYS, TARGET_SYS>
|
||||
|
||||
=back
|
||||
|
||||
The build system has a special target for an amalgamated build, i.e.
|
||||
C<make amalg>. This compiles the LuaJIT core as one huge C file and
|
||||
allows GCC to generate faster and shorter code. Alas, this requires
|
||||
lots of memory during the build. This may be a problem for some users,
|
||||
that's why it's not enabled by default. But it shouldn't be a problem
|
||||
for most build farms. It's recommended that binary distributions use
|
||||
this target for their LuaJIT builds.
|
||||
|
||||
The tl;dr version of the above:
|
||||
|
||||
make amalg PREFIX=/usr && \
|
||||
make install PREFIX=/usr DESTDIR=/tmp/buildroot
|
||||
|
||||
Finally, if you encounter any difficulties, please contact me first,
|
||||
instead of releasing a broken package onto unsuspecting users. Because
|
||||
they'll usually gonna complain to me (the upstream) and not you (the
|
||||
package maintainer), anyway.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file install.html
|
||||
# 25250 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "a" element (`a_34) because it has super-phrasal elements (`br_16) as children.
|
||||
# Deleting phrasal "a" element (`a_28) because it has super-phrasal elements (`br_11) as children.
|
||||
# Deleting phrasal "a" element (`a_25) because it has super-phrasal elements (`br_3) as children.
|
|
@ -0,0 +1,421 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Running LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT has only a single stand-alone executable, called C<luajit> on
|
||||
POSIX systems or C<luajit.exe> on Windows. It can be used to run simple
|
||||
Lua statements or whole Lua applications from the command line. It has
|
||||
an interactive mode, too.
|
||||
|
||||
=head2 Command Line Options
|
||||
|
||||
The C<luajit> stand-alone executable is just a slightly modified
|
||||
version of the regular C<lua> stand-alone executable. It supports the
|
||||
same basic options, too. C<luajit -h> prints a short list of the
|
||||
available options. Please have a look at the E<rchevron> Lua manual for
|
||||
details.
|
||||
|
||||
LuaJIT has some additional options:
|
||||
|
||||
=head2 C<-b[options] input output>
|
||||
|
||||
This option saves or lists bytecode. The following additional options
|
||||
are accepted:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<-l> E<mdash> Only list bytecode.
|
||||
|
||||
=item * C<-s> E<mdash> Strip debug info (this is the default).
|
||||
|
||||
=item * C<-g> E<mdash> Keep debug info.
|
||||
|
||||
=item * C<-n name> E<mdash> Set module name (default: auto-detect from
|
||||
input name)
|
||||
|
||||
=item * C<-t type> E<mdash> Set output file type (default: auto-detect
|
||||
from output name).
|
||||
|
||||
=item * C<-a arch> E<mdash> Override architecture for object files
|
||||
(default: native).
|
||||
|
||||
=item * C<-o os> E<mdash> Override OS for object files (default:
|
||||
native).
|
||||
|
||||
=item * C<-e chunk> E<mdash> Use chunk string as input.
|
||||
|
||||
=item * C<-> (a single minus sign) E<mdash> Use stdin as input and/or
|
||||
stdout as output.
|
||||
|
||||
=back
|
||||
|
||||
The output file type is auto-detected from the extension of the output
|
||||
file name:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<c> E<mdash> C source file, exported bytecode data.
|
||||
|
||||
=item * C<h> E<mdash> C header file, static bytecode data.
|
||||
|
||||
=item * C<obj> or C<o> E<mdash> Object file, exported bytecode data
|
||||
(OS- and architecture-specific).
|
||||
|
||||
=item * C<raw> or any other extension E<mdash> Raw bytecode file
|
||||
(portable).
|
||||
|
||||
=back
|
||||
|
||||
Notes:
|
||||
|
||||
=over
|
||||
|
||||
=item * See also string.dump() for information on bytecode portability
|
||||
and compatibility.
|
||||
|
||||
=item * A file in raw bytecode format is auto-detected and can be
|
||||
loaded like any Lua source file. E.g. directly from the command line or
|
||||
with C<loadfile()>, C<dofile()> etc.
|
||||
|
||||
=item * To statically embed the bytecode of a module in your
|
||||
application, generate an object file and just link it with your
|
||||
application.
|
||||
|
||||
=item * On most ELF-based systems (e.g. Linux) you need to explicitly
|
||||
export the global symbols when linking your application, e.g. with:
|
||||
C<-Wl,-E>
|
||||
|
||||
=item * C<require()> tries to load embedded bytecode data from exported
|
||||
symbols (in C<*.exe> or C<lua51.dll> on Windows) and from shared
|
||||
libraries in C<package.cpath>.
|
||||
|
||||
=back
|
||||
|
||||
Typical usage examples:
|
||||
|
||||
luajit -b test.lua test.out # Save bytecode to test.out
|
||||
luajit -bg test.lua test.out # Keep debug info
|
||||
luajit -be "print('hello world')" test.out # Save cmdline script
|
||||
|
||||
luajit -bl test.lua # List to stdout
|
||||
luajit -bl test.lua test.txt # List to test.txt
|
||||
luajit -ble "print('hello world')" # List cmdline script
|
||||
|
||||
luajit -b test.lua test.obj # Generate object file
|
||||
# Link test.obj with your application and load it with require("test")
|
||||
|
||||
=head2 C<-j cmd[=arg[,arg...]]>
|
||||
|
||||
This option performs a LuaJIT control command or activates one of the
|
||||
loadable extension modules. The command is first looked up in the
|
||||
C<jit.*> library. If no matching function is found, a module named
|
||||
C<jit.E<lt>cmdE<gt>> is loaded and the C<start()> function of the
|
||||
module is called with the specified arguments (if any). The space
|
||||
between C<-j> and C<cmd> is optional.
|
||||
|
||||
Here are the available LuaJIT control commands:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<-jon> E<mdash> Turns the JIT compiler on (default).
|
||||
|
||||
=item * C<-joff> E<mdash> Turns the JIT compiler off (only use the
|
||||
interpreter).
|
||||
|
||||
=item * C<-jflush> E<mdash> Flushes the whole cache of compiled code.
|
||||
|
||||
=item * C<-jv> E<mdash> Shows verbose information about the progress of
|
||||
the JIT compiler.
|
||||
|
||||
=item * C<-jdump> E<mdash> Dumps the code and structures used in
|
||||
various compiler stages.
|
||||
|
||||
=item * C<-jp> E<mdash> Start the integrated profiler.
|
||||
|
||||
=back
|
||||
|
||||
The C<-jv> and C<-jdump> commands are extension modules written in Lua.
|
||||
They are mainly used for debugging the JIT compiler itself. For a
|
||||
description of their options and output format, please read the comment
|
||||
block at the start of their source. They can be found in the C<lib>
|
||||
directory of the source distribution or installed under the C<jit>
|
||||
directory. By default this is C</usr/local/share/luajit-2.0.5/jit> on
|
||||
POSIX systems.
|
||||
|
||||
=head2 C<-O[level]>
|
||||
|
||||
C<-O[+]flag> C<-O-flag>
|
||||
|
||||
C<-Oparam=value>
|
||||
|
||||
This options allows fine-tuned control of the optimizations used by the
|
||||
JIT compiler. This is mainly intended for debugging LuaJIT itself.
|
||||
Please note that the JIT compiler is extremely fast (we are talking
|
||||
about the microsecond to millisecond range). Disabling optimizations
|
||||
doesn't have any visible impact on its overhead, but usually generates
|
||||
code that runs slower.
|
||||
|
||||
The first form sets an optimization level E<mdash> this enables a
|
||||
specific mix of optimization flags. C<-O0> turns off all optimizations
|
||||
and higher numbers enable more optimizations. Omitting the level (i.e.
|
||||
just C<-O>) sets the default optimization level, which is C<-O3> in the
|
||||
current version.
|
||||
|
||||
The second form adds or removes individual optimization flags. The
|
||||
third form sets a parameter for the VM or the JIT compiler to a
|
||||
specific value.
|
||||
|
||||
You can either use this option multiple times (like C<-Ocse -O-dce
|
||||
-Ohotloop=10>) or separate several settings with a comma (like
|
||||
C<-O+cse,-dce,hotloop=10>). The settings are applied from left to right
|
||||
and later settings override earlier ones. You can freely mix the three
|
||||
forms, but note that setting an optimization level overrides all
|
||||
earlier flags.
|
||||
|
||||
Here are the available flags and at what optimization levels they are
|
||||
enabled:
|
||||
|
||||
Flag
|
||||
|
||||
-O1
|
||||
|
||||
-O2
|
||||
|
||||
-O3
|
||||
|
||||
fold
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Constant Folding, Simplifications and Reassociation
|
||||
|
||||
cse
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Common-Subexpression Elimination
|
||||
|
||||
dce
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Dead-Code Elimination
|
||||
|
||||
narrow
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Narrowing of numbers to integers
|
||||
|
||||
loop
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Loop Optimizations (code hoisting)
|
||||
|
||||
fwd
|
||||
|
||||
E<bull>
|
||||
|
||||
Load Forwarding (L2L) and Store Forwarding (S2L)
|
||||
|
||||
dse
|
||||
|
||||
E<bull>
|
||||
|
||||
Dead-Store Elimination
|
||||
|
||||
abc
|
||||
|
||||
E<bull>
|
||||
|
||||
Array Bounds Check Elimination
|
||||
|
||||
sink
|
||||
|
||||
E<bull>
|
||||
|
||||
Allocation/Store Sinking
|
||||
|
||||
fuse
|
||||
|
||||
E<bull>
|
||||
|
||||
Fusion of operands into instructions
|
||||
|
||||
Here are the parameters and their default settings:
|
||||
|
||||
Parameter
|
||||
|
||||
Default
|
||||
|
||||
maxtrace
|
||||
|
||||
1000
|
||||
|
||||
Max. number of traces in the cache
|
||||
|
||||
maxrecord
|
||||
|
||||
4000
|
||||
|
||||
Max. number of recorded IR instructions
|
||||
|
||||
maxirconst
|
||||
|
||||
500
|
||||
|
||||
Max. number of IR constants of a trace
|
||||
|
||||
maxside
|
||||
|
||||
100
|
||||
|
||||
Max. number of side traces of a root trace
|
||||
|
||||
maxsnap
|
||||
|
||||
500
|
||||
|
||||
Max. number of snapshots for a trace
|
||||
|
||||
hotloop
|
||||
|
||||
56
|
||||
|
||||
Number of iterations to detect a hot loop or hot call
|
||||
|
||||
hotexit
|
||||
|
||||
10
|
||||
|
||||
Number of taken exits to start a side trace
|
||||
|
||||
tryside
|
||||
|
||||
4
|
||||
|
||||
Number of attempts to compile a side trace
|
||||
|
||||
instunroll
|
||||
|
||||
4
|
||||
|
||||
Max. unroll factor for instable loops
|
||||
|
||||
loopunroll
|
||||
|
||||
15
|
||||
|
||||
Max. unroll factor for loop ops in side traces
|
||||
|
||||
callunroll
|
||||
|
||||
3
|
||||
|
||||
Max. unroll factor for pseudo-recursive calls
|
||||
|
||||
recunroll
|
||||
|
||||
2
|
||||
|
||||
Min. unroll factor for true recursion
|
||||
|
||||
sizemcode
|
||||
|
||||
32
|
||||
|
||||
Size of each machine code area in KBytes (Windows: 64K)
|
||||
|
||||
maxmcode
|
||||
|
||||
512
|
||||
|
||||
Max. total size of all machine code areas in KBytes
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file running.html
|
||||
# 13720 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1,113 @@
|
|||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Status
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT 2.0 is the current stable branch. This branch is in
|
||||
feature-freeze E<mdash> new features will only be added to LuaJIT 2.1.
|
||||
|
||||
=head2 Current Status
|
||||
|
||||
LuaJIT ought to run all Lua 5.1-compatible source code just fine. It's
|
||||
considered a serious bug if the VM crashes or produces unexpected
|
||||
results E<mdash> please report this.
|
||||
|
||||
Known incompatibilities and issues in LuaJIT 2.0:
|
||||
|
||||
=over
|
||||
|
||||
=item * There are some differences in B<implementation-defined>
|
||||
behavior. These either have a good reason, are arbitrary design choices
|
||||
or are due to quirks in the VM. The latter cases may get fixed if a
|
||||
demonstrable need is shown.
|
||||
|
||||
=item * The Lua B<debug API> is missing a couple of features (return
|
||||
hooks for non-Lua functions) and shows slightly different behavior in
|
||||
LuaJIT (no per-coroutine hooks, no tail call counting).
|
||||
|
||||
=item * Currently some B<out-of-memory> errors from B<on-trace code>
|
||||
are not handled correctly. The error may fall through an on-trace
|
||||
C<pcall> or it may be passed on to the function set with C<lua_atpanic>
|
||||
on x64. This issue will be fixed with the new garbage collector.
|
||||
|
||||
=item * LuaJIT on 64 bit systems provides a B<limited range> of 47 bits
|
||||
for the B<legacy C<lightuserdata>> data type. This is only relevant on
|
||||
x64 systems which use the negative part of the virtual address space in
|
||||
user mode, e.g. Solaris/x64, and on ARM64 systems configured with a 48
|
||||
bit or 52 bit VA. Avoid using C<lightuserdata> to hold pointers that
|
||||
may point outside of that range, e.g. variables on the stack. In
|
||||
general, avoid this data type for new code and replace it with (much
|
||||
more performant) FFI bindings. FFI cdata pointers can address the full
|
||||
64 bit range.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file status.html
|
||||
# 3931 bytes of input
|
||||
#Mon May 14 13:19:16 2018 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
|
@ -0,0 +1 @@
|
|||
See [README-windows](./README-windows.md).
|
|
@ -0,0 +1,238 @@
|
|||
Name
|
||||
====
|
||||
|
||||
README-windows - README for the official 32-bit and 64-bit Windows builds of OpenResty
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
* [Name](#name)
|
||||
* [Description](#description)
|
||||
* [Debugging](#debugging)
|
||||
* [Caveats](#caveats)
|
||||
* [TODO](#todo)
|
||||
* [Details About The Building Process](#details-about-the-building-process)
|
||||
* [Author](#author)
|
||||
* [Copyright & License](#copyright--license)
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The official binary Win32 and Win64 distributions of OpenResty can be downloaded from the following web page:
|
||||
|
||||
https://openresty.org/en/download.html
|
||||
|
||||
To start the NGINX server of the nginx server of the Win32 binary distribution of OpenResty:
|
||||
|
||||
```bash
|
||||
start nginx
|
||||
```
|
||||
|
||||
You can also specify the `-p PATH/` option to override the default server prefix, as in
|
||||
|
||||
```bash
|
||||
cd /path/to/my/openresty/app/
|
||||
start nginx -p $PWD
|
||||
```
|
||||
|
||||
Then you can use the `tasklist` command to check the nginx processes running in the background:
|
||||
|
||||
```console
|
||||
C:\> tasklist /fi "imagename eq nginx.exe"
|
||||
|
||||
Image Name PID Session Name Session# Mem Usage
|
||||
========================= ======== ================ =========== ============
|
||||
nginx.exe 4616 Console 1 7,412 K
|
||||
nginx.exe 5836 Console 1 7,800 K
|
||||
|
||||
```
|
||||
|
||||
One of the two processes is the master process while the other is the worker.
|
||||
|
||||
If you are using the MSYS2 bash instead of the `cmd.exe` console, then you should replace the `/fi` option
|
||||
with `-fi` in the command above instead.
|
||||
|
||||
You can quickly shut down the server like this:
|
||||
|
||||
```bash
|
||||
nginx -s stop
|
||||
```
|
||||
|
||||
or gracefully shut it down like this:
|
||||
|
||||
```bash
|
||||
nginx -s quit
|
||||
```
|
||||
|
||||
You can also forcibly kill the nginx processes via their PIDs with `taskkill`, as in
|
||||
|
||||
```console
|
||||
C:\> taskkill /pid 5488 /F
|
||||
```
|
||||
|
||||
where the PID (5488 in this example) can be found via the aforementioned `tasklist` command.
|
||||
|
||||
Again, you should use the form `-pid` and `-F` for the options if you are in an MSYS2 bash
|
||||
session.
|
||||
|
||||
Similarly, you can use the `nginx -s reload` command to reload nginx configurations without
|
||||
stopping the server. And you can use `nginx -s reopen` to instruct nginx to re-open
|
||||
all the log files.
|
||||
|
||||
You can run the `resty` script like this:
|
||||
|
||||
```console
|
||||
C:\> resty -e "ngx.say('Hello, OpenResty!')"
|
||||
Hello, OpenResty!
|
||||
```
|
||||
|
||||
The `resty` command-line utility requires a Perl interpreter installed in your
|
||||
system and visible to your PATH environment. Any perl distributions should
|
||||
work, including StrawberryPerl, ActivePerl, and MSYS2 perl.
|
||||
recommended though).
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
Debug symbols are enabled even in release builds. So that when things go very wrong,
|
||||
one can still debug things with tools like MSYS2 GDB.
|
||||
|
||||
Inclusion of debug symbols make the binary files (`.exe` and `.dll` files) much larger,
|
||||
but it generally will not load into memory during normal execution on a modern operating
|
||||
system.
|
||||
|
||||
Caveats
|
||||
=======
|
||||
|
||||
The Win32/Win64 port of the NGINX core supports the good old `select` IO multiplexing mechanism
|
||||
only.
|
||||
The I/O Completion Ports (IOCP) feature is *not* supported (yet). So do not use this build
|
||||
for production environments with very high concurrency levels.
|
||||
|
||||
This Win32/Win64 build of OpenResty is mainly for developers who want to develop their applications
|
||||
in native Windows environment (though they eventually push the finished work onto a Linux or *BSD box, most of the time).
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
* Add support for more than one NGINX worker processes.
|
||||
* Add support for concurrent connections more than 1024.
|
||||
* Switch to the Microsoft Visual Studio compiler toolchain for better performance and easier binary
|
||||
package redistribution.
|
||||
* Bundle StrawberryPerl to make command-line utilities like `resty` work out of the box (without
|
||||
manually installing a Perl).
|
||||
* Deliver an alternative Win32/Win64 binary package built with best debugging capabilities (like enabling
|
||||
NGINX debugging logs, disabling C compiler optimizations, and enabling all the assertions and checks).
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Details About The Building Process
|
||||
==================================
|
||||
|
||||
Usually you do not need to worry about how the Win32/Win64 binaries were built on the maintainers''
|
||||
side. But if you do, please read on.
|
||||
|
||||
The Win32/Win64 build of OpenResty is currently built via the MSYS2/MinGW toolchain, including
|
||||
MinGW gcc 7.2.3, MSYS2 perl 5.24.4, MSYS2 bash, MSYS2 make, and etc. Basically, it is currently built via
|
||||
the following commands:
|
||||
|
||||
```bash
|
||||
PCRE=pcre-8.42
|
||||
ZLIB=zlib-1.2.11
|
||||
OPENSSL=openssl-1.1.0h
|
||||
|
||||
mkdir -p objs/lib || exit 1
|
||||
cd objs/lib || exit 1
|
||||
ls ../../..
|
||||
tar -xf ../../../$OPENSSL.tar.gz || exit 1
|
||||
tar -xf ../../../$ZLIB.tar.gz || exit 1
|
||||
tar -xf ../../../$PCRE.tar.gz || exit 1
|
||||
cd ../..
|
||||
|
||||
cd objs/lib/$OPENSSL || exit 1
|
||||
patch -p1 < ../../../patches/openssl-1.1.0d-sess_set_get_cb_yield.patch || exit 1
|
||||
cd ../../..
|
||||
|
||||
./configure \
|
||||
--with-cc=gcc \
|
||||
--with-ipv6 \
|
||||
--prefix= \
|
||||
--with-cc-opt='-DFD_SETSIZE=1024' \
|
||||
--sbin-path=nginx.exe \
|
||||
--with-pcre-jit \
|
||||
--without-http_rds_json_module \
|
||||
--without-http_rds_csv_module \
|
||||
--without-lua_rds_parser \
|
||||
--with-ipv6 \
|
||||
--with-stream \
|
||||
--with-stream_ssl_module \
|
||||
--with-stream_ssl_preread_module \
|
||||
--with-http_v2_module \
|
||||
--without-mail_pop3_module \
|
||||
--without-mail_imap_module \
|
||||
--without-mail_smtp_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_realip_module \
|
||||
--with-http_addition_module \
|
||||
--with-http_auth_request_module \
|
||||
--with-http_secure_link_module \
|
||||
--with-http_random_index_module \
|
||||
--with-http_gzip_static_module \
|
||||
--with-http_sub_module \
|
||||
--with-http_dav_module \
|
||||
--with-http_flv_module \
|
||||
--with-http_mp4_module \
|
||||
--with-http_gunzip_module \
|
||||
--with-select_module \
|
||||
--with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
|
||||
--with-pcre=objs/lib/$PCRE \
|
||||
--with-zlib=objs/lib/$ZLIB \
|
||||
--with-openssl=objs/lib/$OPENSSL \
|
||||
-j9 || exit 1
|
||||
|
||||
make -j9
|
||||
make install
|
||||
```
|
||||
|
||||
where the dependency library source tarballs for OpenSSL, Zlib, and PCRE are downloaded
|
||||
from their official sites, respectively.
|
||||
|
||||
We automate these commands in a dedicated shell script named [build-win32.sh](https://github.com/openresty/openresty/blob/master/util/build-win32.sh).
|
||||
|
||||
Furthermore, we automate the packaging process of the resulting binaries and supporting files
|
||||
with this [package-win32.sh](https://github.com/openresty/openresty/blob/master/util/package-win32.sh)
|
||||
script.
|
||||
|
||||
Usually you can just download and use the binary distribution of OpenResty without
|
||||
installing the build toolchain.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Author
|
||||
======
|
||||
|
||||
Yichun "agentzh" Zhang <agentzh@gmail.com>, OpenResty Inc.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
Copyright & License
|
||||
===================
|
||||
|
||||
This module is licensed under the BSD license.
|
||||
|
||||
Copyright (C) 2015-2019, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,241 +0,0 @@
|
|||
/* Exception handling and frame unwind runtime interface routines.
|
||||
Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* As a special exception, if you include this header file into source
|
||||
files compiled by GCC, this header file does not by itself cause
|
||||
the resulting executable to be covered by the GNU General Public
|
||||
License. This exception does not however invalidate any other
|
||||
reasons why the executable file might be covered by the GNU General
|
||||
Public License. */
|
||||
|
||||
/* This is derived from the C++ ABI for IA-64. Where we diverge
|
||||
for cross-architecture compatibility are noted with "@@@". */
|
||||
|
||||
#ifndef _UNWIND_H
|
||||
#define _UNWIND_H
|
||||
|
||||
#ifndef HIDE_EXPORTS
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Level 1: Base ABI */
|
||||
|
||||
/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is
|
||||
inefficient for 32-bit and smaller machines. */
|
||||
typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
|
||||
typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
|
||||
#if defined(__ia64__) && defined(__hpux__)
|
||||
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
|
||||
#else
|
||||
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
|
||||
#endif
|
||||
typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
|
||||
|
||||
/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
|
||||
consumer of an exception. We'll go along with this for now even on
|
||||
32-bit machines. We'll need to provide some other option for
|
||||
16-bit machines and for machines with > 8 bits per byte. */
|
||||
typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
|
||||
|
||||
/* The unwind interface uses reason codes in several contexts to
|
||||
identify the reasons for failures or other actions. */
|
||||
typedef enum
|
||||
{
|
||||
_URC_NO_REASON = 0,
|
||||
_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
|
||||
_URC_FATAL_PHASE2_ERROR = 2,
|
||||
_URC_FATAL_PHASE1_ERROR = 3,
|
||||
_URC_NORMAL_STOP = 4,
|
||||
_URC_END_OF_STACK = 5,
|
||||
_URC_HANDLER_FOUND = 6,
|
||||
_URC_INSTALL_CONTEXT = 7,
|
||||
_URC_CONTINUE_UNWIND = 8
|
||||
} _Unwind_Reason_Code;
|
||||
|
||||
|
||||
/* The unwind interface uses a pointer to an exception header object
|
||||
as its representation of an exception being thrown. In general, the
|
||||
full representation of an exception object is language- and
|
||||
implementation-specific, but it will be prefixed by a header
|
||||
understood by the unwind interface. */
|
||||
|
||||
struct _Unwind_Exception;
|
||||
|
||||
typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
|
||||
struct _Unwind_Exception *);
|
||||
|
||||
struct _Unwind_Exception
|
||||
{
|
||||
_Unwind_Exception_Class exception_class;
|
||||
_Unwind_Exception_Cleanup_Fn exception_cleanup;
|
||||
_Unwind_Word private_1;
|
||||
_Unwind_Word private_2;
|
||||
|
||||
/* @@@ The IA-64 ABI says that this structure must be double-word aligned.
|
||||
Taking that literally does not make much sense generically. Instead we
|
||||
provide the maximum alignment required by any type for the machine. */
|
||||
} __attribute__((__aligned__));
|
||||
|
||||
|
||||
/* The ACTIONS argument to the personality routine is a bitwise OR of one
|
||||
or more of the following constants. */
|
||||
typedef int _Unwind_Action;
|
||||
|
||||
#define _UA_SEARCH_PHASE 1
|
||||
#define _UA_CLEANUP_PHASE 2
|
||||
#define _UA_HANDLER_FRAME 4
|
||||
#define _UA_FORCE_UNWIND 8
|
||||
#define _UA_END_OF_STACK 16
|
||||
|
||||
/* This is an opaque type used to refer to a system-specific data
|
||||
structure used by the system unwinder. This context is created and
|
||||
destroyed by the system, and passed to the personality routine
|
||||
during unwinding. */
|
||||
struct _Unwind_Context;
|
||||
|
||||
/* Raise an exception, passing along the given exception object. */
|
||||
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
|
||||
|
||||
/* Raise an exception for forced unwinding. */
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
|
||||
(int, _Unwind_Action, _Unwind_Exception_Class,
|
||||
struct _Unwind_Exception *, struct _Unwind_Context *, void *);
|
||||
|
||||
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
|
||||
_Unwind_Stop_Fn,
|
||||
void *);
|
||||
|
||||
/* Helper to invoke the exception_cleanup routine. */
|
||||
extern void _Unwind_DeleteException (struct _Unwind_Exception *);
|
||||
|
||||
/* Resume propagation of an existing exception. This is used after
|
||||
e.g. executing cleanup code, and not to implement rethrowing. */
|
||||
extern void _Unwind_Resume (struct _Unwind_Exception *);
|
||||
|
||||
/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow
|
||||
a normal exception that was handled. */
|
||||
extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
|
||||
|
||||
/* @@@ Use unwind data to perform a stack backtrace. The trace callback
|
||||
is called for every stack frame in the call chain, but no cleanup
|
||||
actions are performed. */
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
|
||||
(struct _Unwind_Context *, void *);
|
||||
|
||||
extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
|
||||
|
||||
/* These functions are used for communicating information about the unwind
|
||||
context (i.e. the unwind descriptors and the user register state) between
|
||||
the unwind library and the personality routine and landing pad. Only
|
||||
selected registers maybe manipulated. */
|
||||
|
||||
extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
|
||||
extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
|
||||
|
||||
extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
|
||||
extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
|
||||
extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
|
||||
|
||||
/* @@@ Retrieve the CFA of the given context. */
|
||||
extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
|
||||
|
||||
extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
|
||||
|
||||
extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
|
||||
|
||||
|
||||
/* The personality routine is the function in the C++ (or other language)
|
||||
runtime library which serves as an interface between the system unwind
|
||||
library and language-specific exception handling semantics. It is
|
||||
specific to the code fragment described by an unwind info block, and
|
||||
it is always referenced via the pointer in the unwind info block, and
|
||||
hence it has no ABI-specified name.
|
||||
|
||||
Note that this implies that two different C++ implementations can
|
||||
use different names, and have different contents in the language
|
||||
specific data area. Moreover, that the language specific data
|
||||
area contains no version info because name of the function invoked
|
||||
provides more effective versioning by detecting at link time the
|
||||
lack of code to handle the different data format. */
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
|
||||
(int, _Unwind_Action, _Unwind_Exception_Class,
|
||||
struct _Unwind_Exception *, struct _Unwind_Context *);
|
||||
|
||||
/* @@@ The following alternate entry points are for setjmp/longjmp
|
||||
based unwinding. */
|
||||
|
||||
struct SjLj_Function_Context;
|
||||
extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
|
||||
extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
|
||||
|
||||
extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException
|
||||
(struct _Unwind_Exception *);
|
||||
extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind
|
||||
(struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
|
||||
extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *);
|
||||
extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *);
|
||||
|
||||
/* @@@ The following provide access to the base addresses for text
|
||||
and data-relative addressing in the LDSA. In order to stay link
|
||||
compatible with the standard ABI for IA-64, we inline these. */
|
||||
|
||||
#ifdef __ia64__
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline _Unwind_Ptr
|
||||
_Unwind_GetDataRelBase (struct _Unwind_Context *_C)
|
||||
{
|
||||
/* The GP is stored in R1. */
|
||||
return _Unwind_GetGR (_C, 1);
|
||||
}
|
||||
|
||||
static inline _Unwind_Ptr
|
||||
_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__)))
|
||||
{
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @@@ Retrieve the Backing Store Pointer of the given context. */
|
||||
extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *);
|
||||
#else
|
||||
extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
|
||||
extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
|
||||
#endif
|
||||
|
||||
/* @@@ Given an address, return the entry point of the function that
|
||||
contains it. */
|
||||
extern void * _Unwind_FindEnclosingFunction (void *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HIDE_EXPORTS
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
#endif /* unwind.h */
|
|
@ -0,0 +1,14 @@
|
|||
--- lua-5.1.5/src/luaconf.h 2008-02-11 08:25:08.000000000 -0800
|
||||
+++ lua-5.1.5-patched/src/luaconf.h 2012-07-04 18:36:05.700067698 -0700
|
||||
@@ -757,6 +757,11 @@
|
||||
** without modifying the main part of the file.
|
||||
*/
|
||||
|
||||
+#undef LUA_COMPAT_VARARG
|
||||
+#undef LUA_COMPAT_MOD
|
||||
+#undef LUA_COMPAT_LSTR
|
||||
+#undef LUA_COMPAT_GFIND
|
||||
+#undef LUA_COMPAT_OPENLIB
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
--- lua-5.1.5/src/Makefile 2012-02-13 12:41:22.000000000 -0800
|
||||
+++ lua-5.1.5-patched/src/Makefile 2013-04-20 22:56:42.921286886 -0700
|
||||
@@ -8,7 +8,7 @@
|
||||
PLAT= none
|
||||
|
||||
CC= gcc
|
||||
-CFLAGS= -O2 -Wall $(MYCFLAGS)
|
||||
+CFLAGS= -g -O2 -Wall $(MYCFLAGS)
|
||||
AR= ar rcu
|
||||
RANLIB= ranlib
|
||||
RM= rm -f
|
|
@ -0,0 +1,23 @@
|
|||
--- lua-5.1.5/Makefile 2008-08-12 08:40:48.000000000 +0800
|
||||
+++ lua-5.1.5-patched/Makefile 2011-03-09 20:56:47.603422483 +0800
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
# How to install. If your install program does not support "-p", then you
|
||||
# may have to run ranlib on the installed liblua.a (do "make ranlib").
|
||||
-INSTALL= install -p
|
||||
-INSTALL_EXEC= $(INSTALL) -m 0755
|
||||
-INSTALL_DATA= $(INSTALL) -m 0644
|
||||
+#INSTALL= install -p
|
||||
+#INSTALL_EXEC= $(INSTALL) -m 0755
|
||||
+#INSTALL_DATA= $(INSTALL) -m 0644
|
||||
#
|
||||
# If you don't have install you can use cp instead.
|
||||
-# INSTALL= cp -p
|
||||
-# INSTALL_EXEC= $(INSTALL)
|
||||
-# INSTALL_DATA= $(INSTALL)
|
||||
+INSTALL= cp -p
|
||||
+INSTALL_EXEC= $(INSTALL)
|
||||
+INSTALL_DATA= $(INSTALL)
|
||||
|
||||
# Utilities.
|
||||
MKDIR= mkdir -p
|
|
@ -0,0 +1,202 @@
|
|||
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
|
||||
index bf9f9be..30aa964 100644
|
||||
--- a/doc/ext_ffi_semantics.html
|
||||
+++ b/doc/ext_ffi_semantics.html
|
||||
@@ -517,17 +517,17 @@ A VLA is only initialized with the element(s) given in the table.
|
||||
Depending on the use case, you may need to explicitly add a
|
||||
<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>
|
||||
|
||||
-<li>If the table has a non-empty hash part, a
|
||||
-<tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
|
||||
-name (as a string key) in the table. Each non-<tt>nil</tt> value is
|
||||
-used to initialize the corresponding field.</li>
|
||||
-
|
||||
-<li>Otherwise a <tt>struct</tt>/<tt>union</tt> is initialized in the
|
||||
+<li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the
|
||||
order of the declaration of its fields. Each field is initialized with
|
||||
-the consecutive table elements, starting at either index <tt>[0]</tt>
|
||||
+consecutive table elements, starting at either index <tt>[0]</tt>
|
||||
or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table
|
||||
element.</li>
|
||||
|
||||
+<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present,
|
||||
+a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
|
||||
+name (as a string key) in the table. Each non-<tt>nil</tt> value is
|
||||
+used to initialize the corresponding field.</li>
|
||||
+
|
||||
<li>Uninitialized fields of a <tt>struct</tt> are filled with zero
|
||||
bytes, except for the trailing VLA of a VLS.</li>
|
||||
|
||||
diff --git a/doc/running.html b/doc/running.html
|
||||
index 7870a5d..97c5c03 100644
|
||||
--- a/doc/running.html
|
||||
+++ b/doc/running.html
|
||||
@@ -250,6 +250,8 @@ are enabled:
|
||||
<tr class="even">
|
||||
<td class="flag_name">abc</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Array Bounds Check Elimination</td></tr>
|
||||
<tr class="odd">
|
||||
+<td class="flag_name">sink</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Allocation/Store Sinking</td></tr>
|
||||
+<tr class="even">
|
||||
<td class="flag_name">fuse</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
diff --git a/src/lj_arch.h b/src/lj_arch.h
|
||||
index 25c2cff..220f3df 100644
|
||||
--- a/src/lj_arch.h
|
||||
+++ b/src/lj_arch.h
|
||||
@@ -300,7 +300,11 @@
|
||||
|
||||
/* Check target-specific constraints. */
|
||||
#ifndef _BUILDVM_H
|
||||
-#if LJ_TARGET_ARM
|
||||
+#if LJ_TARGET_X64
|
||||
+#if __USING_SJLJ_EXCEPTIONS__
|
||||
+#error "Need a C compiler with native exception handling on x64"
|
||||
+#endif
|
||||
+#elif LJ_TARGET_ARM
|
||||
#if defined(__ARMEB__)
|
||||
#error "No support for big-endian ARM"
|
||||
#endif
|
||||
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
|
||||
index 6d7dd5a..241da5a 100644
|
||||
--- a/src/lj_asm_x86.h
|
||||
+++ b/src/lj_asm_x86.h
|
||||
@@ -367,6 +367,18 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
|
||||
return ra_allocref(as, ref, allow);
|
||||
}
|
||||
|
||||
+#if LJ_64
|
||||
+/* Don't fuse a 32 bit load into a 64 bit operation. */
|
||||
+static Reg asm_fuseloadm(ASMState *as, IRRef ref, RegSet allow, int is64)
|
||||
+{
|
||||
+ if (is64 && !irt_is64(IR(ref)->t))
|
||||
+ return ra_alloc1(as, ref, allow);
|
||||
+ return asm_fuseload(as, ref, allow);
|
||||
+}
|
||||
+#else
|
||||
+#define asm_fuseloadm(as, ref, allow, is64) asm_fuseload(as, (ref), (allow))
|
||||
+#endif
|
||||
+
|
||||
/* -- Calls --------------------------------------------------------------- */
|
||||
|
||||
/* Count the required number of stack slots for a call. */
|
||||
@@ -696,7 +708,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
} else { /* Integer to FP conversion. */
|
||||
Reg left = (LJ_64 && (st == IRT_U32 || st == IRT_U64)) ?
|
||||
ra_alloc1(as, lref, RSET_GPR) :
|
||||
- asm_fuseload(as, lref, RSET_GPR);
|
||||
+ asm_fuseloadm(as, lref, RSET_GPR, st64);
|
||||
if (LJ_64 && st == IRT_U64) {
|
||||
MCLabel l_end = emit_label(as);
|
||||
const void *k = lj_ir_k64_find(as->J, U64x(43f00000,00000000));
|
||||
@@ -1829,7 +1841,7 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
|
||||
if (asm_swapops(as, ir)) {
|
||||
IRRef tmp = lref; lref = rref; rref = tmp;
|
||||
}
|
||||
- right = asm_fuseload(as, rref, rset_clear(allow, dest));
|
||||
+ right = asm_fuseloadm(as, rref, rset_clear(allow, dest), irt_is64(ir->t));
|
||||
}
|
||||
if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */
|
||||
asm_guardcc(as, CC_O);
|
||||
@@ -1842,7 +1854,7 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
|
||||
emit_mrm(as, XO_IMUL, REX_64IR(ir, dest), right);
|
||||
} else { /* IMUL r, r, k. */
|
||||
/* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */
|
||||
- Reg left = asm_fuseload(as, lref, RSET_GPR);
|
||||
+ Reg left = asm_fuseloadm(as, lref, RSET_GPR, irt_is64(ir->t));
|
||||
x86Op xo;
|
||||
if (checki8(k)) { emit_i8(as, k); xo = XO_IMULi8;
|
||||
} else { emit_i32(as, k); xo = XO_IMULi; }
|
||||
@@ -2072,7 +2084,7 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
|
||||
Reg r64 = REX_64IR(ir, 0);
|
||||
int32_t imm = 0;
|
||||
lua_assert(irt_is64(ir->t) || irt_isint(ir->t) ||
|
||||
- irt_isu32(ir->t) || irt_isaddr(ir->t));
|
||||
+ irt_isu32(ir->t) || irt_isaddr(ir->t) || irt_isu8(ir->t));
|
||||
/* Swap constants (only for ABC) and fusable loads to the right. */
|
||||
if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
|
||||
if ((cc & 0xc) == 0xc) cc ^= 0x53; /* L <-> G, LE <-> GE */
|
||||
@@ -2109,7 +2121,7 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
|
||||
}
|
||||
}
|
||||
as->curins--; /* Skip to BAND to avoid failing in noconflict(). */
|
||||
- right = asm_fuseload(as, irl->op1, allow);
|
||||
+ right = asm_fuseloadm(as, irl->op1, allow, r64);
|
||||
as->curins++; /* Undo the above. */
|
||||
test_nofuse:
|
||||
asm_guardcc(as, cc);
|
||||
@@ -2146,7 +2158,7 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
|
||||
return;
|
||||
} /* Otherwise handle register case as usual. */
|
||||
} else {
|
||||
- left = asm_fuseload(as, lref, RSET_GPR);
|
||||
+ left = asm_fuseloadm(as, lref, RSET_GPR, r64);
|
||||
}
|
||||
asm_guardcc(as, cc);
|
||||
if (usetest && left != RID_MRM) {
|
||||
@@ -2160,7 +2172,7 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
|
||||
}
|
||||
} else {
|
||||
Reg left = ra_alloc1(as, lref, RSET_GPR);
|
||||
- Reg right = asm_fuseload(as, rref, rset_exclude(RSET_GPR, left));
|
||||
+ Reg right = asm_fuseloadm(as, rref, rset_exclude(RSET_GPR, left), r64);
|
||||
asm_guardcc(as, cc);
|
||||
emit_mrm(as, XO_CMP, r64 + left, right);
|
||||
}
|
||||
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
|
||||
index b81b4e9..7b32e35 100644
|
||||
--- a/src/lj_cconv.c
|
||||
+++ b/src/lj_cconv.c
|
||||
@@ -493,17 +493,19 @@ static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
|
||||
id = df->sib;
|
||||
if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
|
||||
TValue *tv;
|
||||
- int32_t i = *ip;
|
||||
+ int32_t i = *ip, iz = i;
|
||||
if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
|
||||
if (i >= 0) {
|
||||
retry:
|
||||
tv = (TValue *)lj_tab_getint(t, i);
|
||||
if (!tv || tvisnil(tv)) {
|
||||
if (i == 0) { i = 1; goto retry; } /* 1-based tables. */
|
||||
+ if (iz == 0) { *ip = i = -1; goto tryname; } /* Init named fields. */
|
||||
break; /* Stop at first nil. */
|
||||
}
|
||||
*ip = i + 1;
|
||||
} else {
|
||||
+ tryname:
|
||||
tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name)));
|
||||
if (!tv || tvisnil(tv)) continue;
|
||||
}
|
||||
@@ -524,7 +526,6 @@ static void cconv_struct_tab(CTState *cts, CType *d,
|
||||
{
|
||||
int32_t i = 0;
|
||||
memset(dp, 0, d->size); /* Much simpler to clear the struct first. */
|
||||
- if (t->hmask) i = -1; else if (t->asize == 0) return; /* Fast exit. */
|
||||
cconv_substruct_tab(cts, d, dp, t, &i, flags);
|
||||
}
|
||||
|
||||
diff --git a/src/lj_err.c b/src/lj_err.c
|
||||
index 60d8fe1..fd3545e 100644
|
||||
--- a/src/lj_err.c
|
||||
+++ b/src/lj_err.c
|
||||
@@ -485,7 +485,6 @@ LJ_NOINLINE void lj_err_mem(lua_State *L)
|
||||
{
|
||||
if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */
|
||||
lj_vm_unwind_c(L->cframe, LUA_ERRMEM);
|
||||
- L->top = L->base;
|
||||
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
|
||||
lj_err_throw(L, LUA_ERRMEM);
|
||||
}
|
||||
diff --git a/src/lj_parse.c b/src/lj_parse.c
|
||||
index 2fecaef..92ebc04 100644
|
||||
--- a/src/lj_parse.c
|
||||
+++ b/src/lj_parse.c
|
||||
@@ -1825,6 +1825,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ lj_gc_check(fs->L);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
--- LuaJIT-2.1-20151028/src/luaconf.h 2015-10-12 20:28:56.000000000 +0800
|
||||
+++ LuaJIT-2.1-20151028.patched/src/luaconf.h 2015-11-01 20:31:28.358507706 +0800
|
||||
@@ -21,9 +21,9 @@
|
||||
#define LUA_LDIR "!\\lua\\"
|
||||
#define LUA_CDIR "!\\"
|
||||
#define LUA_PATH_DEFAULT \
|
||||
- ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
|
||||
+ ".\\?.lua;" "!\\lualib\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
|
||||
#define LUA_CPATH_DEFAULT \
|
||||
- ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
|
||||
+ ".\\?.dll;" "!\\lualib\\?.so;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
|
||||
#else
|
||||
/*
|
||||
** Note to distribution maintainers: do NOT patch the following lines!
|
|
@ -0,0 +1,117 @@
|
|||
diff -ur nginx-0.8.54/src/http/ngx_http_request_body.c nginx-0.8.54-patched/src/http/ngx_http_request_body.c
|
||||
--- nginx-0.8.54/src/http/ngx_http_request_body.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-0.8.54-patched/src/http/ngx_http_request_body.c 2011-10-21 21:54:08.460350482 +0800
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
r->main->count++;
|
||||
|
||||
- if (r->request_body || r->discard_body) {
|
||||
+ if (r->request_body || r->discard_body || r->content_length_n == 0) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -440,7 +440,7 @@
|
||||
ssize_t size;
|
||||
ngx_event_t *rev;
|
||||
|
||||
- if (r != r->main || r->discard_body) {
|
||||
+ if (r != r->main || r->discard_body || r->content_length_n == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -456,20 +456,22 @@
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
|
||||
- if (r->headers_in.content_length_n <= 0 || r->request_body) {
|
||||
+ r->content_length_n = r->headers_in.content_length_n;
|
||||
+
|
||||
+ if (r->content_length_n <= 0 || r->request_body) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
size = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (size) {
|
||||
- if (r->headers_in.content_length_n > size) {
|
||||
+ if (r->content_length_n > size) {
|
||||
r->header_in->pos += size;
|
||||
- r->headers_in.content_length_n -= size;
|
||||
+ r->content_length_n -= size;
|
||||
|
||||
} else {
|
||||
- r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
- r->headers_in.content_length_n = 0;
|
||||
+ r->header_in->pos += (size_t) r->content_length_n;
|
||||
+ r->content_length_n = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +570,7 @@
|
||||
"http read discarded body");
|
||||
|
||||
for ( ;; ) {
|
||||
- if (r->headers_in.content_length_n == 0) {
|
||||
+ if (r->content_length_n == 0) {
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -577,9 +579,9 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
- size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
+ size = (r->content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
NGX_HTTP_DISCARD_BUFFER_SIZE:
|
||||
- (size_t) r->headers_in.content_length_n;
|
||||
+ (size_t) r->content_length_n;
|
||||
|
||||
n = r->connection->recv(r->connection, buffer, size);
|
||||
|
||||
@@ -596,7 +598,7 @@
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
- r->headers_in.content_length_n -= n;
|
||||
+ r->content_length_n -= n;
|
||||
}
|
||||
}
|
||||
|
||||
Only in nginx-0.8.54-patched/src/http: ngx_http_request_body.c~
|
||||
diff -ur nginx-0.8.54/src/http/ngx_http_request.c nginx-0.8.54-patched/src/http/ngx_http_request.c
|
||||
--- nginx-0.8.54/src/http/ngx_http_request.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-0.8.54-patched/src/http/ngx_http_request.c 2011-10-21 19:06:38.404350692 +0800
|
||||
@@ -286,6 +286,8 @@
|
||||
|
||||
r->pipeline = hc->pipeline;
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
if (hc->nbusy) {
|
||||
r->header_in = hc->busy[0];
|
||||
}
|
||||
@@ -297,6 +299,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
hc->request = r;
|
||||
}
|
||||
|
||||
Only in nginx-0.8.54-patched/src/http: ngx_http_request.c~
|
||||
diff -ur nginx-0.8.54/src/http/ngx_http_request.h nginx-0.8.54-patched/src/http/ngx_http_request.h
|
||||
--- nginx-0.8.54/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-0.8.54-patched/src/http/ngx_http_request.h 2011-10-21 17:26:13.203807584 +0800
|
||||
@@ -366,6 +366,9 @@
|
||||
ngx_pool_t *pool;
|
||||
ngx_buf_t *header_in;
|
||||
|
||||
+ off_t content_length_n;
|
||||
+ /* for discarding request body */
|
||||
+
|
||||
ngx_http_headers_in_t headers_in;
|
||||
ngx_http_headers_out_t headers_out;
|
||||
|
||||
Only in nginx-0.8.54-patched/src/http: ngx_http_request.h~
|
||||
Only in nginx-0.8.54-patched/src/http: tags
|
|
@ -0,0 +1,12 @@
|
|||
--- nginx-0.8.54/src/http/ngx_http_core_module.c 2011-09-27 19:14:02.000000000 +0800
|
||||
+++ nginx-0.8.54-patched/src/http/ngx_http_core_module.c 2011-10-13 15:02:24.414550532 +0800
|
||||
@@ -2542,6 +2542,9 @@
|
||||
r->content_handler = NULL;
|
||||
r->loc_conf = (*clcfp)->loc_conf;
|
||||
|
||||
+ /* clear the modules contexts */
|
||||
+ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
|
||||
+
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
|
@ -0,0 +1,69 @@
|
|||
--- nginx-0.8.54/src/http/ngx_http_variables.c 2011-05-30 05:36:17.000000000 -0700
|
||||
+++ nginx-0.8.54-patched/src/http/ngx_http_variables.c 2011-09-30 10:59:05.000000000 -0700
|
||||
@@ -648,7 +648,17 @@
|
||||
|
||||
a = (ngx_array_t *) ((char *) r + data);
|
||||
|
||||
- n = a->nelts;
|
||||
+ h = a->elts;
|
||||
+ n = 0;
|
||||
+
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ n++;
|
||||
+ }
|
||||
|
||||
if (n == 0) {
|
||||
v->not_found = 1;
|
||||
@@ -659,9 +669,7 @@
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
- h = a->elts;
|
||||
-
|
||||
- if (n == 1) {
|
||||
+ if (n == 1 && a->nelts == 1) {
|
||||
v->len = (*h)->value.len;
|
||||
v->data = (*h)->value.data;
|
||||
|
||||
@@ -670,7 +678,12 @@
|
||||
|
||||
len = - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
- for (i = 0; i < n; i++) {
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
len += h[i]->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
@@ -683,6 +696,11 @@
|
||||
v->data = p;
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
|
||||
if (i == n - 1) {
|
||||
@@ -738,6 +756,10 @@
|
||||
i = 0;
|
||||
}
|
||||
|
||||
+ if (header[i].hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
|
||||
ch = header[i].key.data[n];
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
diff -ur nginx-1.0.10/src/http/ngx_http_request_body.c nginx-1.0.10-patched/src/http/ngx_http_request_body.c
|
||||
--- nginx-1.0.10/src/http/ngx_http_request_body.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_request_body.c 2011-10-21 21:54:08.460350482 +0800
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
r->main->count++;
|
||||
|
||||
- if (r->request_body || r->discard_body) {
|
||||
+ if (r->request_body || r->discard_body || r->content_length_n == 0) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -440,7 +440,7 @@
|
||||
ssize_t size;
|
||||
ngx_event_t *rev;
|
||||
|
||||
- if (r != r->main || r->discard_body) {
|
||||
+ if (r != r->main || r->discard_body || r->content_length_n == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -456,20 +456,22 @@
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
|
||||
- if (r->headers_in.content_length_n <= 0 || r->request_body) {
|
||||
+ r->content_length_n = r->headers_in.content_length_n;
|
||||
+
|
||||
+ if (r->content_length_n <= 0 || r->request_body) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
size = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (size) {
|
||||
- if (r->headers_in.content_length_n > size) {
|
||||
+ if (r->content_length_n > size) {
|
||||
r->header_in->pos += size;
|
||||
- r->headers_in.content_length_n -= size;
|
||||
+ r->content_length_n -= size;
|
||||
|
||||
} else {
|
||||
- r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
- r->headers_in.content_length_n = 0;
|
||||
+ r->header_in->pos += (size_t) r->content_length_n;
|
||||
+ r->content_length_n = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +570,7 @@
|
||||
"http read discarded body");
|
||||
|
||||
for ( ;; ) {
|
||||
- if (r->headers_in.content_length_n == 0) {
|
||||
+ if (r->content_length_n == 0) {
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -577,9 +579,9 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
- size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
+ size = (r->content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
NGX_HTTP_DISCARD_BUFFER_SIZE:
|
||||
- (size_t) r->headers_in.content_length_n;
|
||||
+ (size_t) r->content_length_n;
|
||||
|
||||
n = r->connection->recv(r->connection, buffer, size);
|
||||
|
||||
@@ -596,7 +598,7 @@
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
- r->headers_in.content_length_n -= n;
|
||||
+ r->content_length_n -= n;
|
||||
}
|
||||
}
|
||||
|
||||
Only in nginx-1.0.10-patched/src/http: ngx_http_request_body.c~
|
||||
diff -ur nginx-1.0.10/src/http/ngx_http_request.c nginx-1.0.10-patched/src/http/ngx_http_request.c
|
||||
--- nginx-1.0.10/src/http/ngx_http_request.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_request.c 2011-10-21 19:06:38.404350692 +0800
|
||||
@@ -286,6 +286,8 @@
|
||||
|
||||
r->pipeline = hc->pipeline;
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
if (hc->nbusy) {
|
||||
r->header_in = hc->busy[0];
|
||||
}
|
||||
@@ -297,6 +299,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
hc->request = r;
|
||||
}
|
||||
|
||||
Only in nginx-1.0.10-patched/src/http: ngx_http_request.c~
|
||||
diff -ur nginx-1.0.10/src/http/ngx_http_request.h nginx-1.0.10-patched/src/http/ngx_http_request.h
|
||||
--- nginx-1.0.10/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_request.h 2011-10-21 17:26:13.203807584 +0800
|
||||
@@ -366,6 +366,9 @@
|
||||
ngx_pool_t *pool;
|
||||
ngx_buf_t *header_in;
|
||||
|
||||
+ off_t content_length_n;
|
||||
+ /* for discarding request body */
|
||||
+
|
||||
ngx_http_headers_in_t headers_in;
|
||||
ngx_http_headers_out_t headers_out;
|
||||
|
||||
Only in nginx-1.0.10-patched/src/http: ngx_http_request.h~
|
||||
Only in nginx-1.0.10-patched/src/http: tags
|
|
@ -0,0 +1,20 @@
|
|||
--- nginx-1.0.10/src/event/modules/ngx_epoll_module.c 2011-09-30 22:12:53.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/event/modules/ngx_epoll_module.c 2011-11-30 11:08:46.775817019 +0800
|
||||
@@ -682,6 +682,17 @@
|
||||
wev = c->write;
|
||||
|
||||
if ((revents & EPOLLOUT) && wev->active) {
|
||||
+ if (c->fd == -1 || wev->instance != instance) {
|
||||
+
|
||||
+ /*
|
||||
+ * the stale event from a file descriptor
|
||||
+ * that was just closed in this iteration
|
||||
+ */
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
+ "epoll: stale event %p", c);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
if (flags & NGX_POST_THREAD_EVENTS) {
|
||||
wev->posted_ready = 1;
|
|
@ -0,0 +1,69 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1315324342 -14400
|
||||
# Node ID 4cf0af103bc382a78f894302d1706929a79df4bb
|
||||
# Parent d603ce98fada855f0100b422b7b5672fd22fabea
|
||||
Gzip filter: handle empty flush buffers.
|
||||
|
||||
Empty flush buffers are legitimate and may happen e.g. due to $r->flush()
|
||||
calls in embedded perl. If there are no data buffered in zlib deflate()
|
||||
will return Z_BUF_ERROR (i.e. no progress possible) without adding anything
|
||||
to output. Don't treat Z_BUF_ERROR as fatal and correctly send empty flush
|
||||
buffer if we have no data in output at all.
|
||||
|
||||
See this thread for details:
|
||||
http://mailman.nginx.org/pipermail/nginx/2010-November/023693.html
|
||||
|
||||
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
--- a/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
@@ -758,6 +758,7 @@ static ngx_int_t
|
||||
ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
{
|
||||
int rc;
|
||||
+ ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_gzip_conf_t *conf;
|
||||
|
||||
@@ -769,7 +770,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
rc = deflate(&ctx->zstream, ctx->flush);
|
||||
|
||||
- if (rc != Z_OK && rc != Z_STREAM_END) {
|
||||
+ if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"deflate() failed: %d, %d", ctx->flush, rc);
|
||||
return NGX_ERROR;
|
||||
@@ -818,8 +819,6 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
if (ctx->flush == Z_SYNC_FLUSH) {
|
||||
|
||||
- ctx->zstream.avail_out = 0;
|
||||
- ctx->out_buf->flush = 1;
|
||||
ctx->flush = Z_NO_FLUSH;
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
@@ -827,7 +826,22 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
- cl->buf = ctx->out_buf;
|
||||
+ b = ctx->out_buf;
|
||||
+
|
||||
+ if (ngx_buf_size(b) == 0) {
|
||||
+
|
||||
+ b = ngx_calloc_buf(ctx->request->pool);
|
||||
+ if (b == NULL) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ ctx->zstream.avail_out = 0;
|
||||
+ }
|
||||
+
|
||||
+ b->flush = 1;
|
||||
+
|
||||
+ cl->buf = b;
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
|
@ -0,0 +1,115 @@
|
|||
--- nginx-1.0.10/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
|
@ -0,0 +1,12 @@
|
|||
--- nginx-1.0.10/src/http/ngx_http_core_module.c 2011-09-27 19:14:02.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_core_module.c 2011-10-13 15:02:24.414550532 +0800
|
||||
@@ -2542,6 +2542,9 @@
|
||||
r->content_handler = NULL;
|
||||
r->loc_conf = (*clcfp)->loc_conf;
|
||||
|
||||
+ /* clear the modules contexts */
|
||||
+ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
|
||||
+
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
|
@ -0,0 +1,24 @@
|
|||
diff -ur nginx-1.0.10/auto/cc/gcc nginx-1.0.10-patched/auto/cc/gcc
|
||||
--- nginx-1.0.10/auto/cc/gcc 2011-06-27 19:53:00.205737804 +0800
|
||||
+++ nginx-1.0.10-patched/auto/cc/gcc 2011-06-27 19:53:13.837741087 +0800
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -ur nginx-1.0.10/auto/cc/icc nginx-1.0.10-patched/auto/cc/icc
|
||||
--- nginx-1.0.10/auto/cc/icc 2011-06-27 19:52:56.370157068 +0800
|
||||
+++ nginx-1.0.10-patched/auto/cc/icc 2011-06-27 19:53:19.508916811 +0800
|
||||
@@ -139,7 +139,7 @@
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
|
@ -0,0 +1,90 @@
|
|||
--- nginx-1.0.10/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
|
@ -0,0 +1,504 @@
|
|||
diff -ur nginx-1.0.10/src/core/nginx.h nginx-1.0.10-patched/src/core/nginx.h
|
||||
--- nginx-1.0.10/src/core/nginx.h 2011-08-29 17:30:22.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/core/nginx.h 2011-09-13 12:11:03.135622101 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1000010
|
||||
#define NGINX_VERSION "1.0.10"
|
||||
-#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
diff -ur nginx-1.0.10/src/core/ngx_array.c nginx-1.0.10-patched/src/core/ngx_array.c
|
||||
--- nginx-1.0.10/src/core/ngx_array.c 2008-06-17 23:00:30.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/core/ngx_array.c 2011-09-14 12:02:56.263128538 +0800
|
||||
@@ -39,13 +39,7 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
- }
|
||||
-
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
- }
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,29 +58,17 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ /* allocate a new array */
|
||||
+
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
+
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -100,43 +82,25 @@
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
-
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
/* the array is full */
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
-
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff -ur nginx-1.0.10/src/core/ngx_palloc.c nginx-1.0.10-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.0.10/src/core/ngx_palloc.c 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/core/ngx_palloc.c 2011-09-14 12:03:41.663126519 +0800
|
||||
@@ -8,24 +8,31 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), log);
|
||||
+
|
||||
+ if (d == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ d->next = d;
|
||||
+ d->prev = d;
|
||||
+ d->alloc = NULL;
|
||||
+ p->d = d;
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
@@ -43,7 +50,7 @@
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_large_t *l;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
@@ -55,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
@@ -71,34 +78,45 @@
|
||||
* so we can not use this log while the free()ing the pool
|
||||
*/
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p", d);
|
||||
|
||||
- if (n == NULL) {
|
||||
+ if (n == pool->d) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+ if (pool->d->next == pool->d) {
|
||||
+ ngx_free(pool->d);
|
||||
+ } else {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ ngx_free(d);
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
-
|
||||
- if (n == NULL) {
|
||||
- break;
|
||||
+ if (n == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *tmp;
|
||||
+ ngx_pool_large_t *l;
|
||||
+
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
if (l->alloc) {
|
||||
ngx_free(l->alloc);
|
||||
}
|
||||
@@ -106,109 +124,65 @@
|
||||
|
||||
pool->large = NULL;
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
+ p = pool->d->next;
|
||||
+ while (p != pool->d) {
|
||||
+ tmp = p;
|
||||
+ ngx_free(p->alloc);
|
||||
+ p->prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+ p = p->next;
|
||||
+ ngx_free(tmp);
|
||||
}
|
||||
-}
|
||||
|
||||
+ ngx_free(pool->d->alloc);
|
||||
+ pool->d->alloc = NULL;
|
||||
+
|
||||
+}
|
||||
|
||||
void *
|
||||
-ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
+ ngx_pool_data_t *new;
|
||||
+ void *m;
|
||||
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
+ m = ngx_alloc(size, pool->log);
|
||||
+ if (m == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ new = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (new == NULL){
|
||||
+ ngx_free(m);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ new->alloc = m;
|
||||
+ new->next = pool->d;
|
||||
+ new->prev = pool->d->prev;
|
||||
+ pool->d->prev->next = new;
|
||||
+ pool->d->prev = new;
|
||||
+ return m;
|
||||
}
|
||||
|
||||
-
|
||||
void *
|
||||
-ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
+void *
|
||||
+ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new, *current;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- current = pool->current;
|
||||
-
|
||||
- for (p = current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- current = p->d.next;
|
||||
- }
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
- p->d.next = new;
|
||||
-
|
||||
- pool->current = current ? current : new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +190,6 @@
|
||||
ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
void *p;
|
||||
- ngx_uint_t n;
|
||||
ngx_pool_large_t *large;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
@@ -224,20 +197,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -262,7 +222,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -279,17 +239,41 @@
|
||||
ngx_int_t
|
||||
ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *ll;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large, ll = l; l; ll = l, l = l->next) {
|
||||
if (p == l->alloc) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
"free: %p", l->alloc);
|
||||
ngx_free(l->alloc);
|
||||
l->alloc = NULL;
|
||||
+ if (l == pool->large) {
|
||||
+ pool->large = NULL;
|
||||
+ }
|
||||
+
|
||||
+ ll->next = l->next;
|
||||
+ p = l;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = d->next) {
|
||||
+ if (p == d->alloc) {
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ d->alloc = NULL;
|
||||
+ d->prev->next = d->next;
|
||||
+ d->next->prev = d->prev;
|
||||
+ ngx_free(d);
|
||||
return NGX_OK;
|
||||
}
|
||||
+ if (d->next == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
diff -ur nginx-1.0.10/src/core/ngx_palloc.h nginx-1.0.10-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.0.10/src/core/ngx_palloc.h 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/core/ngx_palloc.h 2011-09-13 12:11:03.155622101 +0800
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
|
||||
typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
struct ngx_pool_large_s {
|
||||
ngx_pool_large_t *next;
|
||||
@@ -45,16 +46,15 @@
|
||||
};
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s{
|
||||
+ ngx_pool_data_t *next;
|
||||
+ ngx_pool_data_t *prev;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
|
@ -0,0 +1,27 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309799136 -14400
|
||||
# Node ID 99e276bba8596bc4df9e638482ee413f4c6bf700
|
||||
# Parent e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
Core: fix body with request_body_in_single_buf.
|
||||
|
||||
If there were preread data and request body was big enough first part
|
||||
of request body was duplicated.
|
||||
|
||||
See report here:
|
||||
http://nginx.org/pipermail/nginx/2011-July/027756.html
|
||||
|
||||
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
|
||||
--- a/src/http/ngx_http_request_body.c
|
||||
+++ b/src/http/ngx_http_request_body.c
|
||||
@@ -372,7 +372,9 @@ ngx_http_do_read_client_request_body(ngx
|
||||
}
|
||||
}
|
||||
|
||||
- if (r->request_body_in_file_only && rb->bufs->next) {
|
||||
+ if (rb->bufs->next
|
||||
+ && (r->request_body_in_file_only || r->request_body_in_single_buf))
|
||||
+ {
|
||||
rb->bufs = rb->bufs->next;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309776931 -14400
|
||||
# Node ID e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
# Parent 610e909bb9e29766188aa86fae3abe0bd3432940
|
||||
Core: fix body if it's preread and there are extra data.
|
||||
|
||||
--- nginx-1.0.10/src/http/ngx_http_request_body.c 2011-07-05 12:11:21.619264633 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_request_body.c 2011-07-05 12:14:30.694321554 +0800
|
||||
@@ -141,6 +141,7 @@
|
||||
|
||||
/* the whole request body was pre-read */
|
||||
|
||||
+ b->last = b->pos + r->headers_in.content_length_n;
|
||||
r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
r->request_length += r->headers_in.content_length_n;
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
diff -ur lz-nginx-1.0.10/nginx-1.0.10/src/core/nginx.h lz-nginx-1.0.10-patched/nginx-1.0.10/src/core/nginx.h
|
||||
--- lz-nginx-1.0.10/nginx-1.0.10/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ lz-nginx-1.0.10-patched/nginx-1.0.10/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1000010
|
||||
#define NGINX_VERSION "1.0.10"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
Only in lz-nginx-1.0.10-patched/nginx-1.0.10/src/core: nginx.h.orig
|
||||
Only in lz-nginx-1.0.10-patched/nginx-1.0.10/src/core: nginx.h.rej
|
||||
diff -ur lz-nginx-1.0.10/nginx-1.0.10/src/http/ngx_http_header_filter_module.c lz-nginx-1.0.10-patched/nginx-1.0.10/src/http/ngx_http_header_filter_module.c
|
||||
--- lz-nginx-1.0.10/nginx-1.0.10/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ lz-nginx-1.0.10-patched/nginx-1.0.10/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: ngx_openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309187571 -14400
|
||||
# Node ID 283a416b2235d5383c12a975edc8866f007fb628
|
||||
# Parent f5fc40783ddcbf4db33859ee2a9bce54cf32c350
|
||||
Core: protect from subrequest loops.
|
||||
|
||||
Without protection subrequest loop results in r->count overflow and
|
||||
SIGSEGV. Protection was broken in 0.7.25.
|
||||
|
||||
Note that this also limits number of parallel subrequests. This
|
||||
wasn't exactly the case before 0.7.25 as local subrequests were
|
||||
completed directly.
|
||||
|
||||
See here for details:
|
||||
|
||||
http://nginx.org/pipermail/nginx-ru/2010-February/032184.html
|
||||
|
||||
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
|
||||
--- a/src/http/ngx_http_core_module.c
|
||||
+++ b/src/http/ngx_http_core_module.c
|
||||
@@ -2287,7 +2287,6 @@ ngx_http_subrequest(ngx_http_request_t *
|
||||
sr->start_sec = tp->sec;
|
||||
sr->start_msec = tp->msec;
|
||||
|
||||
- r->main->subrequests++;
|
||||
r->main->count++;
|
||||
|
||||
*psr = sr;
|
||||
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
|
||||
--- a/src/http/ngx_http_request.c
|
||||
+++ b/src/http/ngx_http_request.c
|
||||
@@ -1981,6 +1981,7 @@ ngx_http_finalize_request(ngx_http_reque
|
||||
if (r == c->data) {
|
||||
|
||||
r->main->count--;
|
||||
+ r->main->subrequests++;
|
||||
|
||||
if (!r->logged) {
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
--- nginx-1.0.10/src/http/ngx_http_variables.c 2011-05-30 20:36:17.000000000 +0800
|
||||
+++ nginx-1.0.10-patched/src/http/ngx_http_variables.c 2011-11-08 22:21:55.229247198 +0800
|
||||
@@ -648,7 +648,17 @@
|
||||
|
||||
a = (ngx_array_t *) ((char *) r + data);
|
||||
|
||||
- n = a->nelts;
|
||||
+ h = a->elts;
|
||||
+ n = 0;
|
||||
+
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ n++;
|
||||
+ }
|
||||
|
||||
if (n == 0) {
|
||||
v->not_found = 1;
|
||||
@@ -659,9 +669,7 @@
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
- h = a->elts;
|
||||
-
|
||||
- if (n == 1) {
|
||||
+ if (n == 1 && a->nelts == 1) {
|
||||
v->len = (*h)->value.len;
|
||||
v->data = (*h)->value.data;
|
||||
|
||||
@@ -670,7 +678,12 @@
|
||||
|
||||
len = - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
- for (i = 0; i < n; i++) {
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
len += h[i]->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
@@ -683,9 +696,14 @@
|
||||
v->data = p;
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
|
||||
- if (i == n - 1) {
|
||||
+ if (--n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -738,6 +756,10 @@
|
||||
i = 0;
|
||||
}
|
||||
|
||||
+ if (header[i].hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
|
||||
ch = header[i].key.data[n];
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
diff -ur nginx-1.0.11/src/http/ngx_http_request_body.c nginx-1.0.11-patched/src/http/ngx_http_request_body.c
|
||||
--- nginx-1.0.11/src/http/ngx_http_request_body.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_request_body.c 2011-10-21 21:54:08.460350482 +0800
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
r->main->count++;
|
||||
|
||||
- if (r->request_body || r->discard_body) {
|
||||
+ if (r->request_body || r->discard_body || r->content_length_n == 0) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -440,7 +440,7 @@
|
||||
ssize_t size;
|
||||
ngx_event_t *rev;
|
||||
|
||||
- if (r != r->main || r->discard_body) {
|
||||
+ if (r != r->main || r->discard_body || r->content_length_n == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -456,20 +456,22 @@
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
|
||||
- if (r->headers_in.content_length_n <= 0 || r->request_body) {
|
||||
+ r->content_length_n = r->headers_in.content_length_n;
|
||||
+
|
||||
+ if (r->content_length_n <= 0 || r->request_body) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
size = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (size) {
|
||||
- if (r->headers_in.content_length_n > size) {
|
||||
+ if (r->content_length_n > size) {
|
||||
r->header_in->pos += size;
|
||||
- r->headers_in.content_length_n -= size;
|
||||
+ r->content_length_n -= size;
|
||||
|
||||
} else {
|
||||
- r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
- r->headers_in.content_length_n = 0;
|
||||
+ r->header_in->pos += (size_t) r->content_length_n;
|
||||
+ r->content_length_n = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +570,7 @@
|
||||
"http read discarded body");
|
||||
|
||||
for ( ;; ) {
|
||||
- if (r->headers_in.content_length_n == 0) {
|
||||
+ if (r->content_length_n == 0) {
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -577,9 +579,9 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
- size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
+ size = (r->content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
NGX_HTTP_DISCARD_BUFFER_SIZE:
|
||||
- (size_t) r->headers_in.content_length_n;
|
||||
+ (size_t) r->content_length_n;
|
||||
|
||||
n = r->connection->recv(r->connection, buffer, size);
|
||||
|
||||
@@ -596,7 +598,7 @@
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
- r->headers_in.content_length_n -= n;
|
||||
+ r->content_length_n -= n;
|
||||
}
|
||||
}
|
||||
|
||||
Only in nginx-1.0.11-patched/src/http: ngx_http_request_body.c~
|
||||
diff -ur nginx-1.0.11/src/http/ngx_http_request.c nginx-1.0.11-patched/src/http/ngx_http_request.c
|
||||
--- nginx-1.0.11/src/http/ngx_http_request.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_request.c 2011-10-21 19:06:38.404350692 +0800
|
||||
@@ -286,6 +286,8 @@
|
||||
|
||||
r->pipeline = hc->pipeline;
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
if (hc->nbusy) {
|
||||
r->header_in = hc->busy[0];
|
||||
}
|
||||
@@ -297,6 +299,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
hc->request = r;
|
||||
}
|
||||
|
||||
Only in nginx-1.0.11-patched/src/http: ngx_http_request.c~
|
||||
diff -ur nginx-1.0.11/src/http/ngx_http_request.h nginx-1.0.11-patched/src/http/ngx_http_request.h
|
||||
--- nginx-1.0.11/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_request.h 2011-10-21 17:26:13.203807584 +0800
|
||||
@@ -366,6 +366,9 @@
|
||||
ngx_pool_t *pool;
|
||||
ngx_buf_t *header_in;
|
||||
|
||||
+ off_t content_length_n;
|
||||
+ /* for discarding request body */
|
||||
+
|
||||
ngx_http_headers_in_t headers_in;
|
||||
ngx_http_headers_out_t headers_out;
|
||||
|
||||
Only in nginx-1.0.11-patched/src/http: ngx_http_request.h~
|
||||
Only in nginx-1.0.11-patched/src/http: tags
|
|
@ -0,0 +1,20 @@
|
|||
--- nginx-1.0.11/src/event/modules/ngx_epoll_module.c 2011-09-30 22:12:53.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/event/modules/ngx_epoll_module.c 2011-11-30 11:08:46.775817019 +0800
|
||||
@@ -682,6 +682,17 @@
|
||||
wev = c->write;
|
||||
|
||||
if ((revents & EPOLLOUT) && wev->active) {
|
||||
+ if (c->fd == -1 || wev->instance != instance) {
|
||||
+
|
||||
+ /*
|
||||
+ * the stale event from a file descriptor
|
||||
+ * that was just closed in this iteration
|
||||
+ */
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
+ "epoll: stale event %p", c);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
if (flags & NGX_POST_THREAD_EVENTS) {
|
||||
wev->posted_ready = 1;
|
|
@ -0,0 +1,69 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1315324342 -14400
|
||||
# Node ID 4cf0af103bc382a78f894302d1706929a79df4bb
|
||||
# Parent d603ce98fada855f0100b422b7b5672fd22fabea
|
||||
Gzip filter: handle empty flush buffers.
|
||||
|
||||
Empty flush buffers are legitimate and may happen e.g. due to $r->flush()
|
||||
calls in embedded perl. If there are no data buffered in zlib deflate()
|
||||
will return Z_BUF_ERROR (i.e. no progress possible) without adding anything
|
||||
to output. Don't treat Z_BUF_ERROR as fatal and correctly send empty flush
|
||||
buffer if we have no data in output at all.
|
||||
|
||||
See this thread for details:
|
||||
http://mailman.nginx.org/pipermail/nginx/2010-November/023693.html
|
||||
|
||||
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
--- a/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
@@ -758,6 +758,7 @@ static ngx_int_t
|
||||
ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
{
|
||||
int rc;
|
||||
+ ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_gzip_conf_t *conf;
|
||||
|
||||
@@ -769,7 +770,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
rc = deflate(&ctx->zstream, ctx->flush);
|
||||
|
||||
- if (rc != Z_OK && rc != Z_STREAM_END) {
|
||||
+ if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"deflate() failed: %d, %d", ctx->flush, rc);
|
||||
return NGX_ERROR;
|
||||
@@ -818,8 +819,6 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
if (ctx->flush == Z_SYNC_FLUSH) {
|
||||
|
||||
- ctx->zstream.avail_out = 0;
|
||||
- ctx->out_buf->flush = 1;
|
||||
ctx->flush = Z_NO_FLUSH;
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
@@ -827,7 +826,22 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
- cl->buf = ctx->out_buf;
|
||||
+ b = ctx->out_buf;
|
||||
+
|
||||
+ if (ngx_buf_size(b) == 0) {
|
||||
+
|
||||
+ b = ngx_calloc_buf(ctx->request->pool);
|
||||
+ if (b == NULL) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ ctx->zstream.avail_out = 0;
|
||||
+ }
|
||||
+
|
||||
+ b->flush = 1;
|
||||
+
|
||||
+ cl->buf = b;
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
|
@ -0,0 +1,115 @@
|
|||
--- nginx-1.0.11/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
|
@ -0,0 +1,14 @@
|
|||
--- nginx-1.0.11/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_request.h 2012-02-20 15:50:43.540762756 +0800
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
|
||||
#define NGX_HTTP_MAX_URI_CHANGES 10
|
||||
-#define NGX_HTTP_MAX_SUBREQUESTS 50
|
||||
+
|
||||
+#ifndef NGX_HTTP_MAX_SUBREQUESTS
|
||||
+#define NGX_HTTP_MAX_SUBREQUESTS 200
|
||||
+#endif
|
||||
|
||||
/* must be 2^n */
|
||||
#define NGX_HTTP_LC_HEADER_LEN 32
|
|
@ -0,0 +1,12 @@
|
|||
--- nginx-1.0.11/src/http/ngx_http_core_module.c 2011-09-27 19:14:02.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_core_module.c 2011-10-13 15:02:24.414550532 +0800
|
||||
@@ -2542,6 +2542,9 @@
|
||||
r->content_handler = NULL;
|
||||
r->loc_conf = (*clcfp)->loc_conf;
|
||||
|
||||
+ /* clear the modules contexts */
|
||||
+ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
|
||||
+
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
|
@ -0,0 +1,24 @@
|
|||
diff -ur nginx-1.0.11/auto/cc/gcc nginx-1.0.11-patched/auto/cc/gcc
|
||||
--- nginx-1.0.11/auto/cc/gcc 2011-06-27 19:53:00.205737804 +0800
|
||||
+++ nginx-1.0.11-patched/auto/cc/gcc 2011-06-27 19:53:13.837741087 +0800
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -ur nginx-1.0.11/auto/cc/icc nginx-1.0.11-patched/auto/cc/icc
|
||||
--- nginx-1.0.11/auto/cc/icc 2011-06-27 19:52:56.370157068 +0800
|
||||
+++ nginx-1.0.11-patched/auto/cc/icc 2011-06-27 19:53:19.508916811 +0800
|
||||
@@ -139,7 +139,7 @@
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
|
@ -0,0 +1,90 @@
|
|||
--- nginx-1.0.11/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
|
@ -0,0 +1,504 @@
|
|||
diff -ur nginx-1.0.11/src/core/nginx.h nginx-1.0.11-patched/src/core/nginx.h
|
||||
--- nginx-1.0.11/src/core/nginx.h 2011-08-29 17:30:22.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/core/nginx.h 2011-09-13 12:11:03.135622101 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1000011
|
||||
#define NGINX_VERSION "1.0.11"
|
||||
-#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
diff -ur nginx-1.0.11/src/core/ngx_array.c nginx-1.0.11-patched/src/core/ngx_array.c
|
||||
--- nginx-1.0.11/src/core/ngx_array.c 2008-06-17 23:00:30.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/core/ngx_array.c 2011-09-14 12:02:56.263128538 +0800
|
||||
@@ -39,13 +39,7 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
- }
|
||||
-
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
- }
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,29 +58,17 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ /* allocate a new array */
|
||||
+
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
+
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -100,43 +82,25 @@
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
-
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
/* the array is full */
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
-
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff -ur nginx-1.0.11/src/core/ngx_palloc.c nginx-1.0.11-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.0.11/src/core/ngx_palloc.c 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/core/ngx_palloc.c 2011-09-14 12:03:41.663126519 +0800
|
||||
@@ -8,24 +8,31 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), log);
|
||||
+
|
||||
+ if (d == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ d->next = d;
|
||||
+ d->prev = d;
|
||||
+ d->alloc = NULL;
|
||||
+ p->d = d;
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
@@ -43,7 +50,7 @@
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_large_t *l;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
@@ -55,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
@@ -71,34 +78,45 @@
|
||||
* so we can not use this log while the free()ing the pool
|
||||
*/
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p", d);
|
||||
|
||||
- if (n == NULL) {
|
||||
+ if (n == pool->d) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+ if (pool->d->next == pool->d) {
|
||||
+ ngx_free(pool->d);
|
||||
+ } else {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ ngx_free(d);
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
-
|
||||
- if (n == NULL) {
|
||||
- break;
|
||||
+ if (n == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *tmp;
|
||||
+ ngx_pool_large_t *l;
|
||||
+
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
if (l->alloc) {
|
||||
ngx_free(l->alloc);
|
||||
}
|
||||
@@ -106,109 +124,65 @@
|
||||
|
||||
pool->large = NULL;
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
+ p = pool->d->next;
|
||||
+ while (p != pool->d) {
|
||||
+ tmp = p;
|
||||
+ ngx_free(p->alloc);
|
||||
+ p->prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+ p = p->next;
|
||||
+ ngx_free(tmp);
|
||||
}
|
||||
-}
|
||||
|
||||
+ ngx_free(pool->d->alloc);
|
||||
+ pool->d->alloc = NULL;
|
||||
+
|
||||
+}
|
||||
|
||||
void *
|
||||
-ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
+ ngx_pool_data_t *new;
|
||||
+ void *m;
|
||||
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
+ m = ngx_alloc(size, pool->log);
|
||||
+ if (m == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ new = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (new == NULL){
|
||||
+ ngx_free(m);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ new->alloc = m;
|
||||
+ new->next = pool->d;
|
||||
+ new->prev = pool->d->prev;
|
||||
+ pool->d->prev->next = new;
|
||||
+ pool->d->prev = new;
|
||||
+ return m;
|
||||
}
|
||||
|
||||
-
|
||||
void *
|
||||
-ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
+void *
|
||||
+ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new, *current;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- current = pool->current;
|
||||
-
|
||||
- for (p = current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- current = p->d.next;
|
||||
- }
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
- p->d.next = new;
|
||||
-
|
||||
- pool->current = current ? current : new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +190,6 @@
|
||||
ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
void *p;
|
||||
- ngx_uint_t n;
|
||||
ngx_pool_large_t *large;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
@@ -224,20 +197,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -262,7 +222,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -279,17 +239,41 @@
|
||||
ngx_int_t
|
||||
ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *ll;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large, ll = l; l; ll = l, l = l->next) {
|
||||
if (p == l->alloc) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
"free: %p", l->alloc);
|
||||
ngx_free(l->alloc);
|
||||
l->alloc = NULL;
|
||||
+ if (l == pool->large) {
|
||||
+ pool->large = NULL;
|
||||
+ }
|
||||
+
|
||||
+ ll->next = l->next;
|
||||
+ p = l;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = d->next) {
|
||||
+ if (p == d->alloc) {
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ d->alloc = NULL;
|
||||
+ d->prev->next = d->next;
|
||||
+ d->next->prev = d->prev;
|
||||
+ ngx_free(d);
|
||||
return NGX_OK;
|
||||
}
|
||||
+ if (d->next == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
diff -ur nginx-1.0.11/src/core/ngx_palloc.h nginx-1.0.11-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.0.11/src/core/ngx_palloc.h 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/core/ngx_palloc.h 2011-09-13 12:11:03.155622101 +0800
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
|
||||
typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
struct ngx_pool_large_s {
|
||||
ngx_pool_large_t *next;
|
||||
@@ -45,16 +46,15 @@
|
||||
};
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s{
|
||||
+ ngx_pool_data_t *next;
|
||||
+ ngx_pool_data_t *prev;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
|
@ -0,0 +1,113 @@
|
|||
--- src/http/modules/ngx_http_fastcgi_module.c
|
||||
+++ src/http/modules/ngx_http_fastcgi_module.c
|
||||
@@ -1501,10 +1501,10 @@ ngx_http_fastcgi_process_header(ngx_http
|
||||
h->lowcase_key = h->key.data + h->key.len + 1
|
||||
+ h->value.len + 1;
|
||||
|
||||
- ngx_cpystrn(h->key.data, r->header_name_start,
|
||||
- h->key.len + 1);
|
||||
- ngx_cpystrn(h->value.data, r->header_start,
|
||||
- h->value.len + 1);
|
||||
+ ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
|
||||
+ h->key.data[h->key.len] = '\0';
|
||||
+ ngx_memcpy(h->value.data, r->header_start, h->value.len);
|
||||
+ h->value.data[h->value.len] = '\0';
|
||||
}
|
||||
|
||||
h->hash = r->header_hash;
|
||||
--- src/http/modules/ngx_http_proxy_module.c
|
||||
+++ src/http/modules/ngx_http_proxy_module.c
|
||||
@@ -1381,8 +1381,10 @@ ngx_http_proxy_process_header(ngx_http_r
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
|
||||
|
||||
- ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
|
||||
- ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
|
||||
+ ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
|
||||
+ h->key.data[h->key.len] = '\0';
|
||||
+ ngx_memcpy(h->value.data, r->header_start, h->value.len);
|
||||
+ h->value.data[h->value.len] = '\0';
|
||||
|
||||
if (h->key.len == r->lowcase_index) {
|
||||
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
|
||||
--- src/http/modules/ngx_http_scgi_module.c
|
||||
+++ src/http/modules/ngx_http_scgi_module.c
|
||||
@@ -941,8 +941,10 @@ ngx_http_scgi_process_header(ngx_http_re
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
|
||||
|
||||
- ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
|
||||
- ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
|
||||
+ ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
|
||||
+ h->key.data[h->key.len] = '\0';
|
||||
+ ngx_memcpy(h->value.data, r->header_start, h->value.len);
|
||||
+ h->value.data[h->value.len] = '\0';
|
||||
|
||||
if (h->key.len == r->lowcase_index) {
|
||||
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
|
||||
--- src/http/modules/ngx_http_uwsgi_module.c
|
||||
+++ src/http/modules/ngx_http_uwsgi_module.c
|
||||
@@ -985,8 +985,10 @@ ngx_http_uwsgi_process_header(ngx_http_r
|
||||
h->value.data = h->key.data + h->key.len + 1;
|
||||
h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
|
||||
|
||||
- ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
|
||||
- ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
|
||||
+ ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
|
||||
+ h->key.data[h->key.len] = '\0';
|
||||
+ ngx_memcpy(h->value.data, r->header_start, h->value.len);
|
||||
+ h->value.data[h->value.len] = '\0';
|
||||
|
||||
if (h->key.len == r->lowcase_index) {
|
||||
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
|
||||
--- src/http/ngx_http_parse.c
|
||||
+++ src/http/ngx_http_parse.c
|
||||
@@ -874,6 +874,10 @@ ngx_http_parse_header_line(ngx_http_requ
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (ch == '\0') {
|
||||
+ return NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
+ }
|
||||
+
|
||||
r->invalid_header = 1;
|
||||
|
||||
break;
|
||||
@@ -936,6 +940,10 @@ ngx_http_parse_header_line(ngx_http_requ
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (ch == '\0') {
|
||||
+ return NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
+ }
|
||||
+
|
||||
r->invalid_header = 1;
|
||||
|
||||
break;
|
||||
@@ -954,6 +962,8 @@ ngx_http_parse_header_line(ngx_http_requ
|
||||
r->header_start = p;
|
||||
r->header_end = p;
|
||||
goto done;
|
||||
+ case '\0':
|
||||
+ return NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
default:
|
||||
r->header_start = p;
|
||||
state = sw_value;
|
||||
@@ -975,6 +985,8 @@ ngx_http_parse_header_line(ngx_http_requ
|
||||
case LF:
|
||||
r->header_end = p;
|
||||
goto done;
|
||||
+ case '\0':
|
||||
+ return NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -988,6 +1000,8 @@ ngx_http_parse_header_line(ngx_http_requ
|
||||
break;
|
||||
case LF:
|
||||
goto done;
|
||||
+ case '\0':
|
||||
+ return NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
default:
|
||||
state = sw_value;
|
||||
break;
|
|
@ -0,0 +1,27 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309799136 -14400
|
||||
# Node ID 99e276bba8596bc4df9e638482ee413f4c6bf700
|
||||
# Parent e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
Core: fix body with request_body_in_single_buf.
|
||||
|
||||
If there were preread data and request body was big enough first part
|
||||
of request body was duplicated.
|
||||
|
||||
See report here:
|
||||
http://nginx.org/pipermail/nginx/2011-July/027756.html
|
||||
|
||||
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
|
||||
--- a/src/http/ngx_http_request_body.c
|
||||
+++ b/src/http/ngx_http_request_body.c
|
||||
@@ -372,7 +372,9 @@ ngx_http_do_read_client_request_body(ngx
|
||||
}
|
||||
}
|
||||
|
||||
- if (r->request_body_in_file_only && rb->bufs->next) {
|
||||
+ if (rb->bufs->next
|
||||
+ && (r->request_body_in_file_only || r->request_body_in_single_buf))
|
||||
+ {
|
||||
rb->bufs = rb->bufs->next;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309776931 -14400
|
||||
# Node ID e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
# Parent 610e909bb9e29766188aa86fae3abe0bd3432940
|
||||
Core: fix body if it's preread and there are extra data.
|
||||
|
||||
--- nginx-1.0.11/src/http/ngx_http_request_body.c 2011-07-05 12:11:21.619264633 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_request_body.c 2011-07-05 12:14:30.694321554 +0800
|
||||
@@ -141,6 +141,7 @@
|
||||
|
||||
/* the whole request body was pre-read */
|
||||
|
||||
+ b->last = b->pos + r->headers_in.content_length_n;
|
||||
r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
r->request_length += r->headers_in.content_length_n;
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
diff -ur lz-nginx-1.0.11/nginx-1.0.11/src/core/nginx.h lz-nginx-1.0.11-patched/nginx-1.0.11/src/core/nginx.h
|
||||
--- lz-nginx-1.0.11/nginx-1.0.11/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ lz-nginx-1.0.11-patched/nginx-1.0.11/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1000011
|
||||
#define NGINX_VERSION "1.0.11"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
Only in lz-nginx-1.0.11-patched/nginx-1.0.11/src/core: nginx.h.orig
|
||||
Only in lz-nginx-1.0.11-patched/nginx-1.0.11/src/core: nginx.h.rej
|
||||
diff -ur lz-nginx-1.0.11/nginx-1.0.11/src/http/ngx_http_header_filter_module.c lz-nginx-1.0.11-patched/nginx-1.0.11/src/http/ngx_http_header_filter_module.c
|
||||
--- lz-nginx-1.0.11/nginx-1.0.11/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ lz-nginx-1.0.11-patched/nginx-1.0.11/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: ngx_openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309187571 -14400
|
||||
# Node ID 283a416b2235d5383c12a975edc8866f007fb628
|
||||
# Parent f5fc40783ddcbf4db33859ee2a9bce54cf32c350
|
||||
Core: protect from subrequest loops.
|
||||
|
||||
Without protection subrequest loop results in r->count overflow and
|
||||
SIGSEGV. Protection was broken in 0.7.25.
|
||||
|
||||
Note that this also limits number of parallel subrequests. This
|
||||
wasn't exactly the case before 0.7.25 as local subrequests were
|
||||
completed directly.
|
||||
|
||||
See here for details:
|
||||
|
||||
http://nginx.org/pipermail/nginx-ru/2010-February/032184.html
|
||||
|
||||
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
|
||||
--- a/src/http/ngx_http_core_module.c
|
||||
+++ b/src/http/ngx_http_core_module.c
|
||||
@@ -2287,7 +2287,6 @@ ngx_http_subrequest(ngx_http_request_t *
|
||||
sr->start_sec = tp->sec;
|
||||
sr->start_msec = tp->msec;
|
||||
|
||||
- r->main->subrequests++;
|
||||
r->main->count++;
|
||||
|
||||
*psr = sr;
|
||||
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
|
||||
--- a/src/http/ngx_http_request.c
|
||||
+++ b/src/http/ngx_http_request.c
|
||||
@@ -1981,6 +1981,7 @@ ngx_http_finalize_request(ngx_http_reque
|
||||
if (r == c->data) {
|
||||
|
||||
r->main->count--;
|
||||
+ r->main->subrequests++;
|
||||
|
||||
if (!r->logged) {
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
diff -ur nginx-1.0.11/src/http/ngx_http_upstream.c nginx-1.0.11-patched/src/http/ngx_http_upstream.c
|
||||
--- nginx-1.0.11/src/http/ngx_http_upstream.c 2011-12-14 02:34:34.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_upstream.c 2012-03-21 21:20:17.333111806 +0800
|
||||
@@ -1385,6 +1385,8 @@
|
||||
|
||||
/* rc == NGX_OK */
|
||||
|
||||
+ u->request_all_sent = 1;
|
||||
+
|
||||
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
||||
if (ngx_tcp_push(c->fd) == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
|
||||
@@ -1451,7 +1453,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
- if (u->header_sent) {
|
||||
+ if (u->request_all_sent) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(c->write, 0);
|
||||
diff -ur nginx-1.0.11/src/http/ngx_http_upstream.h nginx-1.0.11-patched/src/http/ngx_http_upstream.h
|
||||
--- nginx-1.0.11/src/http/ngx_http_upstream.h 2011-11-01 22:18:10.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_upstream.h 2012-03-21 21:18:21.041237173 +0800
|
||||
@@ -313,6 +313,7 @@
|
||||
unsigned buffering:1;
|
||||
|
||||
unsigned request_sent:1;
|
||||
+ unsigned request_all_sent:1;
|
||||
unsigned header_sent:1;
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
--- nginx-1.0.11/src/http/ngx_http_variables.c 2011-05-30 20:36:17.000000000 +0800
|
||||
+++ nginx-1.0.11-patched/src/http/ngx_http_variables.c 2011-11-08 22:21:55.229247198 +0800
|
||||
@@ -648,7 +648,17 @@
|
||||
|
||||
a = (ngx_array_t *) ((char *) r + data);
|
||||
|
||||
- n = a->nelts;
|
||||
+ h = a->elts;
|
||||
+ n = 0;
|
||||
+
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ n++;
|
||||
+ }
|
||||
|
||||
if (n == 0) {
|
||||
v->not_found = 1;
|
||||
@@ -659,9 +669,7 @@
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
- h = a->elts;
|
||||
-
|
||||
- if (n == 1) {
|
||||
+ if (n == 1 && a->nelts == 1) {
|
||||
v->len = (*h)->value.len;
|
||||
v->data = (*h)->value.data;
|
||||
|
||||
@@ -670,7 +678,12 @@
|
||||
|
||||
len = - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
- for (i = 0; i < n; i++) {
|
||||
+ for (i = 0; i < a->nelts; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
len += h[i]->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
@@ -683,9 +696,14 @@
|
||||
v->data = p;
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
+
|
||||
+ if (h[i]->hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
|
||||
- if (i == n - 1) {
|
||||
+ if (--n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -738,6 +756,10 @@
|
||||
i = 0;
|
||||
}
|
||||
|
||||
+ if (header[i].hash == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
|
||||
ch = header[i].key.data[n];
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
diff -ur nginx-1.0.12/src/http/ngx_http_request_body.c nginx-1.0.12-patched/src/http/ngx_http_request_body.c
|
||||
--- nginx-1.0.12/src/http/ngx_http_request_body.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_request_body.c 2011-10-21 21:54:08.460350482 +0800
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
r->main->count++;
|
||||
|
||||
- if (r->request_body || r->discard_body) {
|
||||
+ if (r->request_body || r->discard_body || r->content_length_n == 0) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -440,7 +440,7 @@
|
||||
ssize_t size;
|
||||
ngx_event_t *rev;
|
||||
|
||||
- if (r != r->main || r->discard_body) {
|
||||
+ if (r != r->main || r->discard_body || r->content_length_n == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -456,20 +456,22 @@
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
|
||||
- if (r->headers_in.content_length_n <= 0 || r->request_body) {
|
||||
+ r->content_length_n = r->headers_in.content_length_n;
|
||||
+
|
||||
+ if (r->content_length_n <= 0 || r->request_body) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
size = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (size) {
|
||||
- if (r->headers_in.content_length_n > size) {
|
||||
+ if (r->content_length_n > size) {
|
||||
r->header_in->pos += size;
|
||||
- r->headers_in.content_length_n -= size;
|
||||
+ r->content_length_n -= size;
|
||||
|
||||
} else {
|
||||
- r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
- r->headers_in.content_length_n = 0;
|
||||
+ r->header_in->pos += (size_t) r->content_length_n;
|
||||
+ r->content_length_n = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +570,7 @@
|
||||
"http read discarded body");
|
||||
|
||||
for ( ;; ) {
|
||||
- if (r->headers_in.content_length_n == 0) {
|
||||
+ if (r->content_length_n == 0) {
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -577,9 +579,9 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
- size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
+ size = (r->content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
|
||||
NGX_HTTP_DISCARD_BUFFER_SIZE:
|
||||
- (size_t) r->headers_in.content_length_n;
|
||||
+ (size_t) r->content_length_n;
|
||||
|
||||
n = r->connection->recv(r->connection, buffer, size);
|
||||
|
||||
@@ -596,7 +598,7 @@
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
- r->headers_in.content_length_n -= n;
|
||||
+ r->content_length_n -= n;
|
||||
}
|
||||
}
|
||||
|
||||
Only in nginx-1.0.12-patched/src/http: ngx_http_request_body.c~
|
||||
diff -ur nginx-1.0.12/src/http/ngx_http_request.c nginx-1.0.12-patched/src/http/ngx_http_request.c
|
||||
--- nginx-1.0.12/src/http/ngx_http_request.c 2011-09-30 22:36:19.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_request.c 2011-10-21 19:06:38.404350692 +0800
|
||||
@@ -286,6 +286,8 @@
|
||||
|
||||
r->pipeline = hc->pipeline;
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
if (hc->nbusy) {
|
||||
r->header_in = hc->busy[0];
|
||||
}
|
||||
@@ -297,6 +299,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ r->content_length_n = -1;
|
||||
+
|
||||
hc->request = r;
|
||||
}
|
||||
|
||||
Only in nginx-1.0.12-patched/src/http: ngx_http_request.c~
|
||||
diff -ur nginx-1.0.12/src/http/ngx_http_request.h nginx-1.0.12-patched/src/http/ngx_http_request.h
|
||||
--- nginx-1.0.12/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_request.h 2011-10-21 17:26:13.203807584 +0800
|
||||
@@ -366,6 +366,9 @@
|
||||
ngx_pool_t *pool;
|
||||
ngx_buf_t *header_in;
|
||||
|
||||
+ off_t content_length_n;
|
||||
+ /* for discarding request body */
|
||||
+
|
||||
ngx_http_headers_in_t headers_in;
|
||||
ngx_http_headers_out_t headers_out;
|
||||
|
||||
Only in nginx-1.0.12-patched/src/http: ngx_http_request.h~
|
||||
Only in nginx-1.0.12-patched/src/http: tags
|
|
@ -0,0 +1,20 @@
|
|||
--- nginx-1.0.12/src/event/modules/ngx_epoll_module.c 2011-09-30 22:12:53.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/event/modules/ngx_epoll_module.c 2011-11-30 11:08:46.775817019 +0800
|
||||
@@ -682,6 +682,17 @@
|
||||
wev = c->write;
|
||||
|
||||
if ((revents & EPOLLOUT) && wev->active) {
|
||||
+ if (c->fd == -1 || wev->instance != instance) {
|
||||
+
|
||||
+ /*
|
||||
+ * the stale event from a file descriptor
|
||||
+ * that was just closed in this iteration
|
||||
+ */
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
+ "epoll: stale event %p", c);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
if (flags & NGX_POST_THREAD_EVENTS) {
|
||||
wev->posted_ready = 1;
|
|
@ -0,0 +1,69 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1315324342 -14400
|
||||
# Node ID 4cf0af103bc382a78f894302d1706929a79df4bb
|
||||
# Parent d603ce98fada855f0100b422b7b5672fd22fabea
|
||||
Gzip filter: handle empty flush buffers.
|
||||
|
||||
Empty flush buffers are legitimate and may happen e.g. due to $r->flush()
|
||||
calls in embedded perl. If there are no data buffered in zlib deflate()
|
||||
will return Z_BUF_ERROR (i.e. no progress possible) without adding anything
|
||||
to output. Don't treat Z_BUF_ERROR as fatal and correctly send empty flush
|
||||
buffer if we have no data in output at all.
|
||||
|
||||
See this thread for details:
|
||||
http://mailman.nginx.org/pipermail/nginx/2010-November/023693.html
|
||||
|
||||
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
--- a/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
|
||||
@@ -758,6 +758,7 @@ static ngx_int_t
|
||||
ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
{
|
||||
int rc;
|
||||
+ ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_gzip_conf_t *conf;
|
||||
|
||||
@@ -769,7 +770,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
rc = deflate(&ctx->zstream, ctx->flush);
|
||||
|
||||
- if (rc != Z_OK && rc != Z_STREAM_END) {
|
||||
+ if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"deflate() failed: %d, %d", ctx->flush, rc);
|
||||
return NGX_ERROR;
|
||||
@@ -818,8 +819,6 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
|
||||
if (ctx->flush == Z_SYNC_FLUSH) {
|
||||
|
||||
- ctx->zstream.avail_out = 0;
|
||||
- ctx->out_buf->flush = 1;
|
||||
ctx->flush = Z_NO_FLUSH;
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
@@ -827,7 +826,22 @@ ngx_http_gzip_filter_deflate(ngx_http_re
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
- cl->buf = ctx->out_buf;
|
||||
+ b = ctx->out_buf;
|
||||
+
|
||||
+ if (ngx_buf_size(b) == 0) {
|
||||
+
|
||||
+ b = ngx_calloc_buf(ctx->request->pool);
|
||||
+ if (b == NULL) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ ctx->zstream.avail_out = 0;
|
||||
+ }
|
||||
+
|
||||
+ b->flush = 1;
|
||||
+
|
||||
+ cl->buf = b;
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
|
@ -0,0 +1,115 @@
|
|||
--- nginx-1.0.12/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
|
@ -0,0 +1,14 @@
|
|||
--- nginx-1.0.12/src/http/ngx_http_request.h 2011-08-29 18:39:23.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_request.h 2012-02-20 15:50:43.540762756 +0800
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
|
||||
#define NGX_HTTP_MAX_URI_CHANGES 10
|
||||
-#define NGX_HTTP_MAX_SUBREQUESTS 50
|
||||
+
|
||||
+#ifndef NGX_HTTP_MAX_SUBREQUESTS
|
||||
+#define NGX_HTTP_MAX_SUBREQUESTS 200
|
||||
+#endif
|
||||
|
||||
/* must be 2^n */
|
||||
#define NGX_HTTP_LC_HEADER_LEN 32
|
|
@ -0,0 +1,12 @@
|
|||
--- nginx-1.0.12/src/http/ngx_http_core_module.c 2011-09-27 19:14:02.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_core_module.c 2011-10-13 15:02:24.414550532 +0800
|
||||
@@ -2542,6 +2542,9 @@
|
||||
r->content_handler = NULL;
|
||||
r->loc_conf = (*clcfp)->loc_conf;
|
||||
|
||||
+ /* clear the modules contexts */
|
||||
+ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
|
||||
+
|
||||
ngx_http_update_location_config(r);
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
|
@ -0,0 +1,24 @@
|
|||
diff -ur nginx-1.0.12/auto/cc/gcc nginx-1.0.12-patched/auto/cc/gcc
|
||||
--- nginx-1.0.12/auto/cc/gcc 2011-06-27 19:53:00.205737804 +0800
|
||||
+++ nginx-1.0.12-patched/auto/cc/gcc 2011-06-27 19:53:13.837741087 +0800
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -ur nginx-1.0.12/auto/cc/icc nginx-1.0.12-patched/auto/cc/icc
|
||||
--- nginx-1.0.12/auto/cc/icc 2011-06-27 19:52:56.370157068 +0800
|
||||
+++ nginx-1.0.12-patched/auto/cc/icc 2011-06-27 19:53:19.508916811 +0800
|
||||
@@ -139,7 +139,7 @@
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
|
@ -0,0 +1,90 @@
|
|||
--- nginx-1.0.12/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
|
@ -0,0 +1,504 @@
|
|||
diff -ur nginx-1.0.12/src/core/nginx.h nginx-1.0.12-patched/src/core/nginx.h
|
||||
--- nginx-1.0.12/src/core/nginx.h 2011-08-29 17:30:22.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/core/nginx.h 2011-09-13 12:11:03.135622101 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1000012
|
||||
#define NGINX_VERSION "1.0.12"
|
||||
-#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
diff -ur nginx-1.0.12/src/core/ngx_array.c nginx-1.0.12-patched/src/core/ngx_array.c
|
||||
--- nginx-1.0.12/src/core/ngx_array.c 2008-06-17 23:00:30.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/core/ngx_array.c 2011-09-14 12:02:56.263128538 +0800
|
||||
@@ -39,13 +39,7 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
- }
|
||||
-
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
- }
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,29 +58,17 @@
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ /* allocate a new array */
|
||||
+
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
+
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -100,43 +82,25 @@
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
-
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
/* the array is full */
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
-
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
-
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
-
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff -ur nginx-1.0.12/src/core/ngx_palloc.c nginx-1.0.12-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.0.12/src/core/ngx_palloc.c 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/core/ngx_palloc.c 2011-09-14 12:03:41.663126519 +0800
|
||||
@@ -8,24 +8,31 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), log);
|
||||
+
|
||||
+ if (d == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ d->next = d;
|
||||
+ d->prev = d;
|
||||
+ d->alloc = NULL;
|
||||
+ p->d = d;
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
@@ -43,7 +50,7 @@
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_large_t *l;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
@@ -55,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
@@ -71,34 +78,45 @@
|
||||
* so we can not use this log while the free()ing the pool
|
||||
*/
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p", d);
|
||||
|
||||
- if (n == NULL) {
|
||||
+ if (n == pool->d) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+ if (pool->d->next == pool->d) {
|
||||
+ ngx_free(pool->d);
|
||||
+ } else {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ ngx_free(d);
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
-
|
||||
- if (n == NULL) {
|
||||
- break;
|
||||
+ if (n == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *tmp;
|
||||
+ ngx_pool_large_t *l;
|
||||
+
|
||||
+ for (l = pool->large; l ; l = l->next) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
if (l->alloc) {
|
||||
ngx_free(l->alloc);
|
||||
}
|
||||
@@ -106,109 +124,65 @@
|
||||
|
||||
pool->large = NULL;
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
+ p = pool->d->next;
|
||||
+ while (p != pool->d) {
|
||||
+ tmp = p;
|
||||
+ ngx_free(p->alloc);
|
||||
+ p->prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+ p = p->next;
|
||||
+ ngx_free(tmp);
|
||||
}
|
||||
-}
|
||||
|
||||
+ ngx_free(pool->d->alloc);
|
||||
+ pool->d->alloc = NULL;
|
||||
+
|
||||
+}
|
||||
|
||||
void *
|
||||
-ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
+ ngx_pool_data_t *new;
|
||||
+ void *m;
|
||||
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
+ m = ngx_alloc(size, pool->log);
|
||||
+ if (m == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ new = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (new == NULL){
|
||||
+ ngx_free(m);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ new->alloc = m;
|
||||
+ new->next = pool->d;
|
||||
+ new->prev = pool->d->prev;
|
||||
+ pool->d->prev->next = new;
|
||||
+ pool->d->prev = new;
|
||||
+ return m;
|
||||
}
|
||||
|
||||
-
|
||||
void *
|
||||
-ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
+ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
+void *
|
||||
+ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new, *current;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- current = pool->current;
|
||||
-
|
||||
- for (p = current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- current = p->d.next;
|
||||
- }
|
||||
+ if (size <= 1024) {
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
- p->d.next = new;
|
||||
-
|
||||
- pool->current = current ? current : new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_palloc_large(pool, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +190,6 @@
|
||||
ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
void *p;
|
||||
- ngx_uint_t n;
|
||||
ngx_pool_large_t *large;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
@@ -224,20 +197,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -262,7 +222,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
@@ -279,17 +239,41 @@
|
||||
ngx_int_t
|
||||
ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *l;
|
||||
+ ngx_pool_large_t *ll;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
+ for (l = pool->large, ll = l; l; ll = l, l = l->next) {
|
||||
if (p == l->alloc) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
"free: %p", l->alloc);
|
||||
ngx_free(l->alloc);
|
||||
l->alloc = NULL;
|
||||
+ if (l == pool->large) {
|
||||
+ pool->large = NULL;
|
||||
+ }
|
||||
+
|
||||
+ ll->next = l->next;
|
||||
+ p = l;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = d->next) {
|
||||
+ if (p == d->alloc) {
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+ if (d->alloc) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ }
|
||||
+ d->alloc = NULL;
|
||||
+ d->prev->next = d->next;
|
||||
+ d->next->prev = d->prev;
|
||||
+ ngx_free(d);
|
||||
return NGX_OK;
|
||||
}
|
||||
+ if (d->next == pool->d) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
diff -ur nginx-1.0.12/src/core/ngx_palloc.h nginx-1.0.12-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.0.12/src/core/ngx_palloc.h 2009-12-17 20:25:46.000000000 +0800
|
||||
+++ nginx-1.0.12-patched/src/core/ngx_palloc.h 2011-09-13 12:11:03.155622101 +0800
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
|
||||
typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
struct ngx_pool_large_s {
|
||||
ngx_pool_large_t *next;
|
||||
@@ -45,16 +46,15 @@
|
||||
};
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s{
|
||||
+ ngx_pool_data_t *next;
|
||||
+ ngx_pool_data_t *prev;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
|
@ -0,0 +1,27 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309799136 -14400
|
||||
# Node ID 99e276bba8596bc4df9e638482ee413f4c6bf700
|
||||
# Parent e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
Core: fix body with request_body_in_single_buf.
|
||||
|
||||
If there were preread data and request body was big enough first part
|
||||
of request body was duplicated.
|
||||
|
||||
See report here:
|
||||
http://nginx.org/pipermail/nginx/2011-July/027756.html
|
||||
|
||||
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
|
||||
--- a/src/http/ngx_http_request_body.c
|
||||
+++ b/src/http/ngx_http_request_body.c
|
||||
@@ -372,7 +372,9 @@ ngx_http_do_read_client_request_body(ngx
|
||||
}
|
||||
}
|
||||
|
||||
- if (r->request_body_in_file_only && rb->bufs->next) {
|
||||
+ if (rb->bufs->next
|
||||
+ && (r->request_body_in_file_only || r->request_body_in_single_buf))
|
||||
+ {
|
||||
rb->bufs = rb->bufs->next;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# HG changeset patch
|
||||
# User Maxim Dounin <mdounin@mdounin.ru>
|
||||
# Date 1309776931 -14400
|
||||
# Node ID e7b2f945d55ae44a2295facf9e3336dc4633e5b5
|
||||
# Parent 610e909bb9e29766188aa86fae3abe0bd3432940
|
||||
Core: fix body if it's preread and there are extra data.
|
||||
|
||||
--- nginx-1.0.12/src/http/ngx_http_request_body.c 2011-07-05 12:11:21.619264633 +0800
|
||||
+++ nginx-1.0.12-patched/src/http/ngx_http_request_body.c 2011-07-05 12:14:30.694321554 +0800
|
||||
@@ -141,6 +141,7 @@
|
||||
|
||||
/* the whole request body was pre-read */
|
||||
|
||||
+ b->last = b->pos + r->headers_in.content_length_n;
|
||||
r->header_in->pos += (size_t) r->headers_in.content_length_n;
|
||||
r->request_length += r->headers_in.content_length_n;
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
diff -ur lz-nginx-1.0.12/nginx-1.0.12/src/core/nginx.h lz-nginx-1.0.12-patched/nginx-1.0.12/src/core/nginx.h
|
||||
--- lz-nginx-1.0.12/nginx-1.0.12/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ lz-nginx-1.0.12-patched/nginx-1.0.12/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1000012
|
||||
#define NGINX_VERSION "1.0.12"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
Only in lz-nginx-1.0.12-patched/nginx-1.0.12/src/core: nginx.h.orig
|
||||
Only in lz-nginx-1.0.12-patched/nginx-1.0.12/src/core: nginx.h.rej
|
||||
diff -ur lz-nginx-1.0.12/nginx-1.0.12/src/http/ngx_http_header_filter_module.c lz-nginx-1.0.12-patched/nginx-1.0.12/src/http/ngx_http_header_filter_module.c
|
||||
--- lz-nginx-1.0.12/nginx-1.0.12/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ lz-nginx-1.0.12-patched/nginx-1.0.12/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: ngx_openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue