netsurf: branch vince/pdf updated. release/3.9-260-g1debcc5
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/1debcc54c6bc897dc1192...
...commit http://git.netsurf-browser.org/netsurf.git/commit/1debcc54c6bc897dc119237...
...tree http://git.netsurf-browser.org/netsurf.git/tree/1debcc54c6bc897dc11923734...
The branch, vince/pdf has been updated
discards bae4db1b59737e95bd11c60ca7f0abe7f1b6d994 (commit)
discards 6f543d129bf6f73baefacf9ae5af19c0d2a74c2e (commit)
discards 689faa4fbb3d07dd4277f138b0c9b75c96577978 (commit)
discards 7eea4ef0b049a751506b7021264290cea07dc85c (commit)
discards 57a45534c988e0bc83affee2a890d8ee60692e8f (commit)
discards 1b4614b66a8adfecba244c4fa4dfa9b2ecbfac47 (commit)
discards e6a2ff5bba7adc092a7af8f9604d0a440e535624 (commit)
via 1debcc54c6bc897dc11923734501e4ce23923475 (commit)
via dd422bb7045f958adb5bab9786209d6a825f2613 (commit)
via f819d17bb20ccdb7430deb56ebd3722cfbd3148b (commit)
via c3a96c0797caca6a9bf905697d7a27dc461bf036 (commit)
via 2b6659f4adc97bbcfc4488c3ce65da36a195712a (commit)
via f7e377dc5383097fd301d67858c2b9f0a95defdf (commit)
via 8ca79d6013ae99f37b4be94a3390f5be34a02477 (commit)
via ca40e217685d04f83459645a660c891a18b01def (commit)
via 1dd9f4f2e44b17d38c5b109b573e3eb17c13420b (commit)
via ff7dd5419f0f7ae11846227bb65454d4b311f105 (commit)
via b37fdcd7e2fbb1fd820efc158b79fcbde3c276ca (commit)
via ca20dab9cfe3c0fe71ba6057a7d22aae575e949c (commit)
via f3cb3188c6cc4d04ce6be8e7fae54f80a12429e8 (commit)
via 40aa44e4f50dd35cbc11332b1c1865b3152afb2d (commit)
via 737a09d53e57b6ca7bba82e4e579056127fec17f (commit)
via d5490be98aa754906fb55dce445f1eb581a29edc (commit)
via 6c470679ee23f85ff291a1a68319289fbd807696 (commit)
via 9dd936ae7c1380061d35a763a728f5ad2bded798 (commit)
via 9d3112a643d2ff1c6055133485273d5e5a358d24 (commit)
via e14416d43fea0da0aca91a3373ed3c67a28af183 (commit)
via bebb883d5a8165aab90153a227f37e55de8f267b (commit)
via cbb818aa64b21e20954d06a4c5374a065d61088f (commit)
via 9b03d6ba6372298ad4df171003d35d54fe0c772c (commit)
via 4efb1d34c3b5cbce0fdac1eca45da88600e7f3c7 (commit)
via f6f8102ecb4e0281e5f0373464481185d2fa3b04 (commit)
via 25581133a11800600ad290fa84fc3ca11927116c (commit)
via 2bed178a339a5dfb05159f6efed2f283a2c2eb2d (commit)
via 12cca32059cc871245571f59af5e09816fbea094 (commit)
via d94afaa0e1bc2d50c68d562f4b5751cd469fa4cb (commit)
via e9b5b56ba61283901b8d04c0f84929664ee29bb3 (commit)
via a013a24d5f489ee5295aa1ce0bfe68c9c27e327f (commit)
via a20fe23ce611a156ba7f10d555436b3ad9f8b72f (commit)
via 9bbc7eb9cbde19ff594ce5901fdf7bf1faac2874 (commit)
via 541acda906e6d725468aa31bcc95f43d1cca23d4 (commit)
via 11aa682154af6e0d4c7920bb2983df5a6ded126f (commit)
via 9cd9a403e6ee69c78a575872bd399c633862d5aa (commit)
via 3df34e7dec892632851aa2774bab41f2dc708574 (commit)
via a8e186f120617a2f29a0673947734b65fad7995f (commit)
via 7b63f36a4f748d0a265c50c933181e1582484b77 (commit)
via db558f862bdf3c4a6392ab3b3b5bcacaf87b29bd (commit)
via c7ad2553d8a001d1dfc492a816b7b507836e05e9 (commit)
via dbc5b5df6af05e2218de3d07fcc602ae88520b57 (commit)
via df398ed886a020c5044239f43b0d73faa323545e (commit)
via 778c05a1949b61fbe37b06313e5b1e3c0f05f7e4 (commit)
via 608cc3cbbfae27498268442aa31ef791894e0789 (commit)
via 747f135de5785e2a43ff4b27e07559d3aacd3377 (commit)
via fc4ad51a66785979280b0609a39a3051dbc7d4a0 (commit)
via c7c89daff3f04d2ccc78905c128e7dfa938543d4 (commit)
via 46e1116aaa38793ff3a36fb5ff05e3be448df49f (commit)
via 65d5161558cfd749f58de89990b739865f2bccaa (commit)
via 635be1dfb88c01ab6a901f6e88eb3b7187d2c03b (commit)
via bcb2b7a2c4425ba888f6236890d35a8f2d037360 (commit)
via 11197074102a46cb85d108f0915fc2929e79b26a (commit)
via 5f5b94c2aee697e2da5ab6819b19a00b83f50390 (commit)
via 061499eef611ed39831a38384bba42d71d0e58c1 (commit)
via 64b2f355dc8b1779996f9cb981b1e9ddebd7d7cd (commit)
via ec62f346e11bc17c9d7c9955697503f309162fb3 (commit)
via f6a669464f67bbed442c80cb3b6d207eacf4fa9a (commit)
via 85b65921ed38b3ce0bd795e9455afbd53610b309 (commit)
via 2e8861dc05325c88cfb8130e7eddd0967e4d4b09 (commit)
via e84990bc891c7a75930fddd614516d3eb170cd75 (commit)
via e36338b6177df9617c89e2eae4f3fcb0a77d7b5b (commit)
via 08d7c55cc536211784a24df179719a802435ff0b (commit)
via 45bd456cd86bd300ea51285c969b88e6ae68bbb9 (commit)
via 7f115dc9268776a63084fe5e1cefa5852d6b2ff0 (commit)
via 8f0c0734eaf27429b4ca6c2c89517a3b5d476d87 (commit)
via 8eebe695f053abb390ddc9894415f595ad7f4177 (commit)
via b24b28e40eb84e1ed361224b172928582b471e10 (commit)
via ff64341ed33d8abf722795ca4d51d81ce02d7694 (commit)
via c297101c3a7b9b40ff08f120cb92c8a9b4237e5e (commit)
via b389dd4116fc5a313a015328a068a968223a4daf (commit)
via f3a68771e34511a07a42374c0c0a656ed8d47905 (commit)
via 305190fe730cf19e0556ff8e24cbf85e63566de0 (commit)
via 07a9d5b3fb1c8d956d453e998c5903527f99f5e4 (commit)
via 8b5100a97e302ea11b00c9780c5071703ddf2027 (commit)
via 869c16dae60b519013bde67c443ce737bbb20ccf (commit)
via bd90138b482c8561927c2d6a75c172415e583a16 (commit)
via dd767acfee416a65e67193a9740d2b636b868e11 (commit)
via 02c75d07900d4566a8b2f835fb07a4eff1ab8235 (commit)
via 89fb88f6dee5322beb3161497cab7a848cb9a4a8 (commit)
via 65d169da106d159d9fb53ceb55a5b5899cc0762f (commit)
via 1fc51d1f4482243cc7d2a10517f04dcc471cef8e (commit)
via 63fc84a25f97c811259dbf1af51fc045b95c5659 (commit)
via 8b0aec4bac4af7fe119227280ed15bf014f104c3 (commit)
via b03786920aa4aff2194d2e9c94e8301546897ae9 (commit)
via 4065f1e0278d6d6d644bbf927b80125cf999a7bb (commit)
via 6c2d97bf01c25f2af6fd41a741ca0f74230fd8f5 (commit)
via 2d87e7ebeacb33836f8c959a00bb059ff3683963 (commit)
via 524965b867e9aaef4ba75d6e077fdfd6c0b88401 (commit)
via cb33f696a2683e7e848a0444f52945f2f56acc28 (commit)
via df496cc8bcbe2e4bc0687fd3e8e678686d37b5cc (commit)
via 9a3f138f9240f2865f5b15a6892da5b7434c2ae7 (commit)
via 2538d05bb4b04b0c438e303e8bd67aec28bd3506 (commit)
via b67bbe3280ebdfdfdc4731d977ad7a38b9608c2a (commit)
via 6bce06b91f5efe51531aa4923137488cf21df132 (commit)
via 4dc4d8b318c9bee25ca9b2982495b2906cc76287 (commit)
via c0e27bd0da9c6804c788473b891bff6c0c98af66 (commit)
via 01f3879b647e69684ef8cbcc53f44b2c9b7b5df8 (commit)
via 44f3846727d35ab17be3f779caa4a33548cdc152 (commit)
via c903c881e62ce020f53da0b03f4e8f388b9bd986 (commit)
via 5cd45cf7f0093b6b5518d753e4d2738902c8dc35 (commit)
via 22ae220bf618a2be98142fde365201ca2142853b (commit)
via 4094232e3d3b877c62d04be87f749e7d2dcbf82d (commit)
via 1e9bfcda7e21505dfeb2b5f3de3ad7a3eb287001 (commit)
via 7f6222babe788418b02dbe251854b9e3d566f04a (commit)
via ccd81015a1d0f72af32210270da61fdd09d87d0b (commit)
via 6a1dbd377b437e227b17c0521986550208bf4a3d (commit)
via a3c3b2fa976a0679b40c85c3afb89e66cd8d1bfb (commit)
via ef75d670d6537ac1bdf46c363843e801005907b2 (commit)
via 765c9c6654c3b1a8b5af07bb4632021f111e26f1 (commit)
via bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73 (commit)
via 78199c017782067bda94307c7bfc9dc9c1f1eefd (commit)
via faec17a90362fe53a952083472199e0d69d747b1 (commit)
via 820fb0e7ff3103cff00778364df0390f4b3de513 (commit)
via 98f45250734fc7a2826753a143d7c37fc522f604 (commit)
via c6a2c76867cbb6f108eb31e8eb9df0db51114dd5 (commit)
via 3a23e944dd1a81a1e9b7b3acf0c13d53a0669d5d (commit)
via 746010a7573baa68f831627c5965314d96bed5d5 (commit)
via 1b030bd8dea17ca1d91f68ee05f935e711e747be (commit)
via 8cec045cb7b433a0c0fc8000ad6bd09f67aaa0c8 (commit)
via 1cf1ec55bc7647e737d7ec41bfe1def721269c02 (commit)
via 75349e79d82c43b9731b9349364f467c81fce94b (commit)
via 8469f4cc8e62e80a3165a1d4f13b62b5b4a04720 (commit)
via 9c9c26a308995c22210c90e3772e86f49a1948b9 (commit)
via 6a1c64ff7b45dd830bfdb5e1295830b75c531f61 (commit)
via ea549da8df0ab4ebed2b1f79cd215ac2bd0918e2 (commit)
via 5e45c4498c0a8a24330864b3d4c68ffe891ce15e (commit)
via c238325b12318803a8dcc706d7d678333f82e1c8 (commit)
via a8889226126d85736da82c767abf705872c00d7e (commit)
via 5775e3941169952517eab741bb6e2262b48f6584 (commit)
via 49a82109ce2f4d44e92dfbbb4ad59311f54bad03 (commit)
via 040d558d39072c42cbc763e07fa7ac0d8a0b3c80 (commit)
via 865844ede7ffa096c83149657f7223ccda405c2e (commit)
via ddfa76b1fc172d0701bee3e8762e97c354fd67cf (commit)
via 03c6ae381277562c6a42635ac80973b68b484917 (commit)
via f3ac1fad69952a21b3609d110e6e81eb6a0a2c00 (commit)
via 9318ee5d6a668a4c816cc82af9cd86ae826e30b7 (commit)
via 99984dfc57a5562a5f2fc624e143b24fd5543af3 (commit)
via be23d522db03f412bc9a855aac7598419336d4f1 (commit)
via 170dc5d52419450edc440c054a94135c1cc1296a (commit)
via bfb1bb119241d85bb9b400881328496e12a39aed (commit)
via bccf101714f2ca165b1fd754879f3813993d26ca (commit)
via 2be3ebd91868436abcbbd581b3e661cdd6f95559 (commit)
via 6ba199c7d7bee1909107ee0b8cbaf749c575b310 (commit)
via 2171f13ab334716250ca2bc53946806f7a88c8a3 (commit)
via 936cb3ce0c746011af67c2b4f0e6df5070c9d9e6 (commit)
via 243659763bfc97800f94332b941cc7195f2edde1 (commit)
via b15b204f4958f039573868c02093f3aa2ae48e98 (commit)
via 05c6ee02d99ea04dde6687d94508b40f4393f77b (commit)
via e78dc4f5a945f2035f48c8dc01cd3b1d76f03c81 (commit)
via bf0e6be9cad29ade1acd114f664af38f6de2f801 (commit)
via 0aae3c370ba498d726eda40b71d2259c00f86a24 (commit)
via 077237a4df2b576e972ff2d98b9c35175536ccd5 (commit)
via 13276f56549f1c03cf485fb39c4f683a3ea4d3c7 (commit)
via 98f8eaeb31ec77f37fdc30d4a28e889c663c7d3b (commit)
via 3be2b98cc2d5c4e7c97a6caba86d1869893f25eb (commit)
via c88a55999a93f80462b01d25388172c67df0dc72 (commit)
via 1651dc2fb142430046c83e2158335f1200149483 (commit)
via f21c41a2e549e22e523118e8d8f2c881c0f088a7 (commit)
via b2f5c80ef82c2e76bd33f58b6454031500c98504 (commit)
via 19052001541aeac269b846d2a81e7f78e7c26c2d (commit)
via 3bd7a2ddd6fc84127625a7fce43dfc9e215a6d7f (commit)
via 6b4610edc9bfe67692a2182afc584ea4e6fa5cb9 (commit)
via b48e462f0f542f82db95d9b8613339a9b748808e (commit)
via f59a726f6899bd970ab5c1b853323442a6a9e473 (commit)
via 386d803371c94a4b10154fa544374dc7b09fb14a (commit)
via 90fe920e07c78e4f65f5df84498c570892e5e2c0 (commit)
via a0fbf56a1da97e74e7b5dc00a2d0643ed2b60639 (commit)
via 6d81f87c73244e16125b4dbf9ae2d35eda582ce3 (commit)
via 337c2ed7b171d757516d6a828a062366f2d783e8 (commit)
via 31ef86a016f0d27eea4f3b581aec0a0f796f619f (commit)
via 357e8a8ad289d8b12ab1f5b89ef07383487381e2 (commit)
via 4e95b7aedfcf3f18d1b21b3c5d68078539fe844f (commit)
via 09eb89e3c3b7ce98d66369ca5d6c41283caf9873 (commit)
via 84a9c5accf63a5cfdbf288f3aba137fc5945aa02 (commit)
via 1866f3a3d1fa710a84bf1ed9b948075156f10c7b (commit)
via a1951f4c49a44783478c7000bd5ac5d349375488 (commit)
via 01485d06baf0098c2f0ec3ac48ea49150e550de9 (commit)
via 342b65fd76de0b26cda3fecf2140b547b5e11b2e (commit)
via 11ecf0b6712d1817beef9a5907f462adf89c3d33 (commit)
via 3938d5340b4d44dfe9c7839d1dc2bd790607f8ff (commit)
via 8cff4b79d602b4437a81f3e008f22caf276d102a (commit)
via 641f5fb07204a9deb256557902707cd28182463d (commit)
via 402e16e5d1e88a3844b900c485d9fc7c4093f2ab (commit)
via d4c01894c21559cd4199c0f15b9e8b7bec4b692c (commit)
via 0ebfff259fa4ec6aaf5e97a213d5c65c24052e96 (commit)
via 0a8ed41a1ad470bb62c908d0dc6272c1c541a1f2 (commit)
via 182c4ddefe6c1cd050361febb344ccd8cd5d1c96 (commit)
via 54daff0e979a17984d66b06db2adc292f55b7b14 (commit)
via f984873799b30f5bad45f58e456f6f5e8c384c16 (commit)
via 6826e5d612848a6c94b73d9d1cc54250ee0f17b5 (commit)
via 41ecb495d0d27e2911a08c52330d1e58483c345c (commit)
via 45097c7f396df40b9c0cf71f2dd3dbeb50fc10c8 (commit)
via 69d1d5f626c637aef352cfd35eeb800760f909b1 (commit)
via 404fc65771a3b13d5376ea000b3549ee541cc91c (commit)
via 3a4477413a62ef928c26c4137dfc6668d22df297 (commit)
via acad436d681d49d87056f43847e5712848693404 (commit)
via 813a284e9e4fe4f4b1482de18488414636abad2b (commit)
via ab03b204ba42e79dd5047ffb2867043495a8b802 (commit)
via a08a1a1d1451e43fd7a2b3a0e7967e3095313992 (commit)
via f98de0d3474c98ea3a477340420c0e782533a803 (commit)
via 99cb0d6bc6dcf313a33f3784f684f40f193c5b9f (commit)
via 7c2811f5f66b8dce0e39057048922cceef94eb7f (commit)
via 5e8b2d46535f61cfeda79c1571f52cd210d4b429 (commit)
via c078c3f50932f9fc0bcb20ed8ddaaf648f6acda2 (commit)
via 818f4018d2a2e8a16e2c65c97ecd56c2f583f2c1 (commit)
via 1ee32fe96275798c465375cf1d990c11749c63af (commit)
via ad67eeff4bfe15c2aaf2c6b537a8327825687411 (commit)
via 6bbdf08cb09d6e893056af72b5e7b47ef9fe7d5a (commit)
via 4421d1bab6529132ee8b8988d2c2e538002906f5 (commit)
via f7d97d64836a042effd52a894ed8b1abeff46960 (commit)
via 6a9137f4319951b370b5b94e5d3049d6430e031d (commit)
via 1150cf684d7b9a47fb6780d4bf22cd3d89df28da (commit)
via 1f24336d6c3c496ac020981c4e1907508579422c (commit)
via 09cce349da9cad23e5475e3974dab50b7a947201 (commit)
via c9384d65f6fb5d6c661f9f65c4b60956e7d4bc1a (commit)
via 0eb5aa68fbb321477c7e6e0b0452bf1a4186fd99 (commit)
via 15a3c2123245a97c9baf569c51d0b030a68df25a (commit)
via ee338c9b24958bfe61a40ee5a4bc0df096134790 (commit)
via 1c2a0021b315659cdbdf9f1723f95a9d56427b1d (commit)
via 80116bfe9f0a9e3b8a19bd448997e1d4c28e1110 (commit)
via 22a348fa31a7ed6d2b2c90eeb13b1e5b39b13440 (commit)
via f320725307e26f8fde4e9d3dc7a436c2f557154f (commit)
via b4bbca89cd5a3f182cf3e18afaa2e222724fde9f (commit)
via 3114e78ded112f2c75b52b77734cb7b238705278 (commit)
via 552aab42e16689c24ac566913b02c7613bfc090b (commit)
via 4ae27a65929a5fe333dc9f9f0d43ac91a72a0116 (commit)
via 5c9d54d05b35f3f06261f8bf9c3a48d2293df767 (commit)
via 095a0639d30b2683e028d632379bf7f7ac1ae6ae (commit)
via d196dee05b8dc5245da32629bc8f7759cf55a62a (commit)
via 9742a8317f66cc2802b3d92456ec0516a6de8c79 (commit)
via 6683818c182d396d17ea8bde035a91da20da9e9c (commit)
via 3fcba68fcffb7fba55be54d1beab9184e96f2b3a (commit)
via 609ee9b71c6c3965451261924e57538f03d80ae2 (commit)
via ce7e6d91f50c3e204a2bb5521c616d1f94b63143 (commit)
via 955cf5f97b9a2d906a6052e0ad681f344afb9600 (commit)
via 654840e8452696bcc23633ca857c3a1fa0155d1e (commit)
via 2943e9ae467050ce359cb40d45081d79e6128ac5 (commit)
via de12be4e9ce1640ed047345a5f22757470f7c77d (commit)
via e85e2f7cdf58e0df1faba9a4868113eba9890edd (commit)
via f365e75407bc9964c09613f80de0b64eb6055975 (commit)
via bb3e0e51f1cbae2134b7891c44a24bccc2f7f255 (commit)
via 7f612548e747d60f65d8f331ba68dbd00191a16a (commit)
via 57427620704c707fa5d50eb6f01a5c4654708c4c (commit)
via f4f67698eb6eb92a8ac606f771401c0c480d0ad5 (commit)
via 83c9d2017f16be6ef42a590e1eff76006a897d67 (commit)
via acee5faa3f03a229a6d7d14e042441a6af048faf (commit)
via 87177d8aa109206d131e0d80a2080ce55dab01c7 (commit)
via c798d18a607ac010784e473f98f24c01a3fc4fb5 (commit)
via 335b0dc38b0e67e6714a871beab6f0ada146ae2f (commit)
via ba9f5f8ef0ac7a1c6bb6dbfee63006a44902ca6d (commit)
via c90bfb23adf10c0497b120a868df2d9bb8cafd86 (commit)
via fa64763b0d8c6566eda5f6547e7f2f3e62b77613 (commit)
via 6c951f7a15a46763992685aae238cdab44483cce (commit)
via a325d6b4745824422ac0f69d3bb87244d8c92109 (commit)
via 22ee6621fe7592daab1665e4318415c39ec689ed (commit)
via 4b6967fee487262d73aca83226647b5d428f5e6d (commit)
via 5ee910ffee2763e75805a61c8e9e69841d0932b0 (commit)
via f4878b4c170dca059f2a9538a2949d12f49e682e (commit)
via 83adc89eb752b916c28631edc89854a04eb6fb18 (commit)
via 1fe63cd67775bb08ff452e3e1b42abeec22e989e (commit)
via f7d4b485cb14bf41fea3c523f5f5874711c238ea (commit)
via 730d59776a33ba2633a4978eb0bdb0020061bfb3 (commit)
via 90530c419e3393675ef37718986fce6f85d8a772 (commit)
via cfdaf181a28c463e041ee55585b8d559fd14aed9 (commit)
via c2fa6af0ff4098501560bd48f78dfbf9173f4021 (commit)
via f46b77160a0244b83ccd486df82ce14f7a4df59e (commit)
via ccf336bb4a46c5d66eb1b50a532db059b9c4fc8e (commit)
via e01bbee4056786d08fbaf8f347fa17033a8f3e62 (commit)
via 1ae0ee21eef94f5bc82f64543384698bd0b7ebec (commit)
via 43f8e77df7c36ceaa7b8851b779cf81661a686d3 (commit)
via 6a53b447e5726bc7d7b8405b1b1dd958c701b007 (commit)
via 1c3ce67c62cccd8a32090e770f0cba62e9945f28 (commit)
via ca2cbac232f0d048eadc948e60f91f09471f6ac9 (commit)
via 4368c4c04268f6528eb8bcc1ff83ee679f6f13bf (commit)
via a57940a468e7abd65cc2d69d3f8a167b0f4e4dfc (commit)
via 8b31e18ad685017c25ced3c0d8e43d7a7dff8384 (commit)
via dc9762fef3aa5e4e026cfff49eb05466160e5442 (commit)
via 8265b8b66f7072a659dbc0f3e50fe23d6d6a68a1 (commit)
via 84b8e7dfa12455118187f0b8d352461f886bc3aa (commit)
via e14a6598be6c8c3ab2071422abd3cf92ec8801fb (commit)
via 659c9161ee037bb523891ac3e3b00748cec6289f (commit)
via 09fa61eb737aa93fb2e99d383c46bcf35d5d730d (commit)
via 1d5a024a68be4ce6558eeffacb8ef6fb5f5a1417 (commit)
via 5c0eee43e2965d1e8b34b5a7b275de308cc09cc1 (commit)
via 8b6f590aaa8d110ef6f62befb792827c16d7e75a (commit)
via 1951c0f8094ab74abd1873e622a8a79f2627c7fc (commit)
via c90bd806a68a4d5e80ff985ad626e14cc8605204 (commit)
via c1dc4e61bd87abdfc120888e79c2da6bad8ce26b (commit)
via 23698aecf844c105b210fa42b642c1d0203978c9 (commit)
via 047c82cfce53102aced0f76f5ca13fe3c56b4db2 (commit)
via 04b790643b9e45a1ba8919481f3c4beb80a66c31 (commit)
via 9893b05b084980ff498eee6dd17853d8df807f27 (commit)
via e598dcd139d8221f828d542ccf6f03466a5aecdc (commit)
via 24590a1145f3d9e6a2842d51b426157da653be5d (commit)
via 93494790f31b4a0bb36827bc60e00e97559482f8 (commit)
via 7314651b9506d9810ce15c45811894e4e6a89107 (commit)
via e82107a29611f9d77a8699bac625df4524563137 (commit)
via 03624bcf7a0128979be1a9c60852cb230b9dc0db (commit)
via c5c8a492764d9e31a6d4cf87ae0fd16245ea7805 (commit)
via 04cf2fe588987e58bb17e83b2a2c39f73a6bd23c (commit)
via dddc5eac944746b766ac1009d2b7063cabab0d3d (commit)
via c74c8332acc3e323565281f3f2774bf088a6a882 (commit)
via eeeca4b712cd99290348a37f143535c3c33fb116 (commit)
via 4be18fcf473b5bff57daa1b57e3de961134a546a (commit)
via f2000ae60efaf8f296dd4e2719417224cd99ac59 (commit)
via 64ee8e1b00438ea87ba10ea6dd34e6d3000c28ce (commit)
via 27ee92c8721f982b79432689dbcb5439bb4fadc2 (commit)
via 3d80e825e1c77ece19c21ed1cc568049856a44de (commit)
via 41608a73c0539ce6e1a030121df2a6515cca644c (commit)
via c07b2edd7783a3c03145180126d3d6dcbfaba604 (commit)
via 9c32564085de877b9fd98aeddc09812fe9b6efb5 (commit)
via a6de56583c56e2d438639b58b0ce1eb4b64a941a (commit)
via 19de453ad5cedab3cfb91d34f3c0b57baa0904a6 (commit)
via 295617b451df93734c36e18917589e31e9088c60 (commit)
via c47cc0888327d2d820b500ad31c17c932a94709a (commit)
via 13a5b8f74a9024953a27e4c34740d05e9a4e3e8e (commit)
via 57094c84edeb3540e13121dea742b1ae484d468b (commit)
via 196c2fc845713d7ce2072a48f560f326b90b733a (commit)
via 87be4e7a1771753f5b64550510684098559b7146 (commit)
via c42039c546d20c8734318eed04da3a478bfe0cac (commit)
via 9ee92823e2a3890e526faf8956916c6fd987958a (commit)
via 78385629c3c6ad95b76ae494d8d9e683dc239216 (commit)
via 12bba5a1cc36c8c8b32c0714173bd81bd32e8cb8 (commit)
via ea9bc4e2bef98278e4df2b84666c6419d74d2f52 (commit)
via cb178b43bebd3217325fcd4de7ee6826ff48e002 (commit)
via 5bd54f4c0ca6d3e0c5afbaecba7ebd63e66529fd (commit)
via 2db39b1f7d813fa7a3fbe22744ff2d56463f81b7 (commit)
via a5e4bf82202b6352d89ba5e7bbf2f04b2c3ee786 (commit)
via f139c4fa4dc2b64367966cd68a84f9b1747b14b1 (commit)
via 336a7dc17044f966c0e0390bce740b61ac0a3cdb (commit)
via 6ac65a367462367addea548be8bd0051980feead (commit)
via 24b910f4ff72b24a871c7d66f9e5f5992625c975 (commit)
via a5051c7128ee7ee9b0bc26a81ad7eb3af199d7ca (commit)
via 97010ecef521de524846734e093db89a18f81f62 (commit)
via c5a07fac76313c2d2d6348dee20d881a639c40c8 (commit)
via 8f9d434b1295215c377eab2ba7186ad8b2d92aa9 (commit)
via 95b8d129508ccdec5eadabf46eb313b49a6b4369 (commit)
via 896e531a7fb6874a0a52de746ea8f783a5f9b441 (commit)
via 944d8fc412241e278b6302d9498925bea6ce9657 (commit)
via 19742c826aca5494a1f10e3a869190531e7ae25b (commit)
via 76618d958869859666cc0e33a414d2b2ffed9dcf (commit)
via df5c18315ff13e215f661eacd2d81e3c0a758e57 (commit)
via d0df3fa4b340071fbe54f9e7966f62b873b52b81 (commit)
via 1cd30fdb3c1f163beceb0bde7485c10a886de531 (commit)
via ae36d35728f8622396faba7aeb58434aff2d0331 (commit)
via a5aa53657c6feaf8ddd29ee33f8d5e89138ec996 (commit)
via 1edf8f28480fcb780dc6504022c65b6cc6c019cf (commit)
via c64d48005c31a7046f224b796a3da5ac0e79751d (commit)
via 4713e1c8af2e4defbc127150838bd35549038b7b (commit)
via ca1a519cfad66978c18181b4a544b485f69aee90 (commit)
via b9dd0a60c300b0de6b117500f67b6724b520652c (commit)
via 83c38318530678b81fa837e8c330107c97f447e2 (commit)
via 67af746324d830914c78e8ab216eb4e37a4163a3 (commit)
via 6d1f480f011a2de630ebe99e68effc725f179ed1 (commit)
via 5c7b5476f0739e5f62071800830b7600a64a3dd5 (commit)
via b330fd9f0ef3e923f47537690c3ef05fc55498cd (commit)
via 31655be43bb6a1eda4f53a6d2a5d5a35c2a89232 (commit)
via 51feeadcf953d5a4e1876e61350184e11fe1f154 (commit)
via 041e9426c1be16709f620757e79c68843058f43f (commit)
via ffc199d778c7666edca028da965009574fdfd3df (commit)
via 7567f6407512acb44199a11b6496a614ca659fe2 (commit)
via e02020198da093a4856b149c926668c32cfcc7a4 (commit)
via 1736bdcfee86a776ab3a9a6b74b2f9646688bb9c (commit)
via a43b83de0369228b935b693390186e5a8804340d (commit)
via 65b16f4c54eba748ee4c8b6580e6f08fc27534f8 (commit)
via 0db71994ea8ffd8a95b38b4ca415bc76d75a3acf (commit)
via 0f3b27916733bb8d962a8fd9434422421d489e23 (commit)
via b38f7cc7187a257f5fb04864ad2f44c4466c1ddc (commit)
via 6ad7b3e6080d7faf534e4a1865d77741b870b727 (commit)
via d77ed689e69c6db402cf8311b402f073172c35b1 (commit)
via 52ef77ceef3f2b2e1ba094aa8cd5c6b4494a91a0 (commit)
via 654e1ee12ac3d405b4a98735179d749dc0047d05 (commit)
via 378383ea3bf04ab6e083c597298db63ff665837e (commit)
via d719bdcee3bf4cae2649535251d69a33839ae13a (commit)
via 3e3a8e9549d45b2068617337b9b14f6b42896259 (commit)
via a4da4612c283531e16558412bf45a527ceb1d9f2 (commit)
via cdc77136621a67396b08eba0cacf6bfc6f79b809 (commit)
via 2c49123a270b2e723c76516750e9325eb6ab99dc (commit)
via dbf02c37f4f1652561b9542530dd93b3ba310e9f (commit)
via 183f9ed8bc4be1f379e365fae5f47dbb348b7978 (commit)
via 4db81370f3ad8d4812020394fec453131eb089bf (commit)
via 6bbb672c577bc02a77e199f0152ad4538dcc32ab (commit)
via dd96a69573e7a45b5ac4a2b172319d900c89f53b (commit)
via 10930fcbaf985bdc414e9a7951dc8a0e3e9d53f6 (commit)
via 6fdc692aa523a642770747042c82153933fa734c (commit)
via 1be9127ee70d4850f54b2e7b21bdd06f465bfe08 (commit)
via 2b8531ff490a8f262a4f416e8568fdd9dabb5bfd (commit)
via 0312c45d6f616fdfb6cddabb0689f60a06f86df3 (commit)
via d24017474174614c630fbfde1c53415cf1a6fdfa (commit)
via d27027d4ba21921365737e358b3d26e2159488c3 (commit)
via 35bc2ccbb89a6b499e0e3b6f7095afea214f0c59 (commit)
via f966580d22d47ab97bceb2f067fc2b9402af01b7 (commit)
via 8dc78699374dca5b8369ffa65a6e27a3eeb8f985 (commit)
via 67da94a5375a88104b6c31a8acde93cfdeb75c26 (commit)
via 846e811760eb79965a844546d50c49c31768fbee (commit)
via 8b4ec11b8958b7b7893d2b0f6aad20b2ddc3599f (commit)
via 8474c5d4c0b59e74e2ef001b5033b78d7a99fcad (commit)
via 6952a239465811c26838e177d35222fd5229e393 (commit)
via 5e1f4c406d63139e2eff1fbd004e4f33b0ad20d1 (commit)
via fb1d9862f993861a13224f80e0aaae696476fa05 (commit)
via 47e47244a9dc397293dbf94c9f1e22f715b95ff4 (commit)
via c76b5ef4d548429b5ee3ee87ddd5d917431afd34 (commit)
via 3ba50e85747d31deaa2c4c17950b46fc50019564 (commit)
via ac512958ffb8382b7d7c76748dc69c7ea49baf70 (commit)
via e27df0c0b8081f06fec44562b87b35dc0ad434a3 (commit)
via 689458aa6e1ad02e15dbd8f48d8a87bd933ec149 (commit)
via 3021142aadf58bf65da1619d3ead92281beaffeb (commit)
via 1146f8bf49eda7f23960e2efdd6dcefb6a98b552 (commit)
via f3892c98fdc734a0abca136ab712c94246fe66c0 (commit)
via ec0028bdb96a03f83055f2798c498a36142d6b03 (commit)
via efdea7757b3bbdb4e092844b30be091d066cfe79 (commit)
via 9a3b644bf01f746d8e0c57706277ab0bd4ec8002 (commit)
via 4394dbd9d48920f270351f7ad0dbb18b5bc5b598 (commit)
via d566debc48a4c706213dfcd5ac6154d0920cdb12 (commit)
via 6dfc0f1486e50ff6a3bb74164cc5e0af6b012deb (commit)
via 38a65c0242ca7b32aa74537ab72d52510a9a32c8 (commit)
via e8cd7c661499c8bfca26026e6291f1ed81c29194 (commit)
via 5dca74b911df9dae01c7f0b77b6bdce6ece94bcf (commit)
via 274b4a2d2eb1375f611b846a53e0cf13501574fe (commit)
via 2f1526653f107d3feaaec5317d373d2888de2e2d (commit)
via 85a4792280290e7a2ce12ec200032dee1848ad12 (commit)
via ed829a477222f169e4ff0727db920e8029fd0c7d (commit)
via 8009444918b167e8499c8abb06e406d9769c38e8 (commit)
via 83f24af275fae0fd89960a5d49e06b9be9987fe0 (commit)
via 9769e8f2c067b8f5bbebe3bede0ab223dbae357d (commit)
via 36d83668c2070fb5085137178900dff7d3017e08 (commit)
via e4f57437f6ef0f0fc25f8ca2846ea606cb22c017 (commit)
via 99809ee64669da845f28808361ebd7e7dea5fd6c (commit)
via a03b4a3c14768b262547ebc64b12b12f09910eef (commit)
via 920d6fa23dcf954a280812feeae4baf02fcaeb57 (commit)
via 637b4e5fc0ddb5db17b09778567cbad373d36beb (commit)
via 19b45fb494358838be8b3175fde9e3ab55ef5bfa (commit)
via 90cabaf8c88782a07cd8bdc448bd21e471eeb072 (commit)
via ed9894d75011667dfaeba18fceb11411f21fe60b (commit)
via 9e1b4218a185c9681c4d09f8fc5348bcccb00b22 (commit)
via 598ceebb46ea365817b1448c769175d524a91d18 (commit)
via dd02849df06762bc878cf78d95cdbcfe37ddbee3 (commit)
via 8eab64132ac105d1e9fdcf34fb760d895d005d39 (commit)
via b2e4c2ec580c353121d787833ba8409fef743916 (commit)
via 1b04b2fb21b485de3f59b49646845e67ded9a55f (commit)
via 4f9a373960a7bfdcc586d1b90bc75a8aea282aa7 (commit)
via 2739a47d83c44ae3aac13d11f17ce5fbefc4c5a2 (commit)
via 177a0477522c03ddd28237704a8ab2d1b2ea0dd8 (commit)
via 61143e0bd261dcb325335d41443204a806abe792 (commit)
via c17e588b66360e984241a80077ce986a9182f0de (commit)
via 35e9b5de6d59436568d9cbb951c98e716716bd7e (commit)
via 519f0294205389dbf809fd2de206dcf21187bcfc (commit)
via 148639b70c3831693c08bb00d5ef372d59088840 (commit)
via ccb499b80057a8241829a3ba11e5f87013739c8d (commit)
via 1a170f9f322416e14b0b11b999b61efa6bcdf8fe (commit)
via ac46ecbc1c2e756af6c2decfbd5e0a9d332fa781 (commit)
via 35dbf07440cb6c5c26e1dbe2f7cd83ad95b745e1 (commit)
via 178d4bc25c0fe781f955b32f0056cf1723c39481 (commit)
via 0a72449f4bf189cd2fb9e69d72fe582420957a21 (commit)
via 7c9066b49faed1a4f614a4f2a3f4f6462b377d25 (commit)
via d0a9fc3e35113e8734d10338856a43599f98d50c (commit)
via 7d402ebc460ec5a11eab526cc52b4d6430496df3 (commit)
via 446fd392e85fa8ac527c2e1938889ea0781cca6d (commit)
via 6455a2ea83493165641be350e3dfe1dd93af5dea (commit)
via 826474a1a3707bb837bb1b1aa687d4981acd914d (commit)
via 13a7004e6b152494eeab677774cdb626b9e1541d (commit)
via 61891ada50f1407778292cf104c595192f73b17c (commit)
via f367b23d7204ec2296419ba578e8f6ecaa9f0deb (commit)
via 00ce87551c6516f7e1510129fe1b01763c756fdc (commit)
via 070c74b64822b40d2f80164ce5e207720506ef2e (commit)
via 6185b254ca92638b45102743a6accf0894f7a890 (commit)
via 09bbb4571b7343ab0c3163e46e8d37b3e0e02ee1 (commit)
via e2d5ef5ebeea422dc5fd6117f3acf860ba7ab671 (commit)
via d4d57bc0ed0cd4a14aeb572c0d13600e2a3457eb (commit)
via 41eed8eeaf54861c28ff37800ad2e27341946330 (commit)
via f64da1abda3d39fc3e76d49ef111d6f0c71469c0 (commit)
via e1a3e0427f7166bf0e1c85520080bb75c6ee24c1 (commit)
via 07242c7415bcfb35d3f9f150317b30138664eb2f (commit)
via 776b0242a6221df61c8d1c7b320f223de5af8466 (commit)
via 54371c28f07e638694ad2148e8900e1bae71e3d4 (commit)
via cfb6c461fc61c64cf39e4708922ad024ac5fce91 (commit)
via e4457f6179a000009176c5f0dce63b985a076b78 (commit)
via 883b202c58eed5158abc3e73c5e6bccda8bdbff3 (commit)
via 5bda316fb3b62cc5d6efe466e822293615b8586b (commit)
via d4b3889227a4ea507f9b419f893effbc76146868 (commit)
via ceefe452052c58ee092da5cdc9c505c3b84f0392 (commit)
via 1698a752827858125e3e4626168cdaa29f13d6d3 (commit)
via f33db7d4429f14c215933c28853813c46f97f11e (commit)
via b25c7b3d2d3da854755208e05e43cbe787f389ae (commit)
via 2e50e1ea71232998d610449bb3a1fe8902580f43 (commit)
via 9952ef000c95013b8a9f50289f9e33d4477b8cb6 (commit)
via 29ce303eb0fce688645c3f4f3a5abbf5e765a9eb (commit)
via 231f026e6a518db00695b4c18c7f41b6c8698942 (commit)
via d1fa6a8ee1e53aebd8d3a7baa3b27f27e71972c2 (commit)
via 9501c9e68d336f894470d45a317f9a2123dcca80 (commit)
via 83798a83b77be8c6cf3778c93ac5e0611865935b (commit)
via c6f92f2f2a8a3d16c9c4e791049a3c7c93854c07 (commit)
via 413929dad5a0bffc41d0c66df9cc80689a23c00f (commit)
via 0a3a40c23eeb22a4ec6e463ca2287df9e337f8ff (commit)
via 3d12bfe595e930ecef231884b1f192306373358b (commit)
via 7d1e8a75fb0a6366927ac255ad2ae5c394ed1ddf (commit)
via 05ac4303058588a77b12e25951d378498a9b3449 (commit)
via 7264ff6f4da719671eb170cb23d80d7fe4c2d1fe (commit)
via 3fd6f04e520872efa19ba2a9fd22b324d8104f2e (commit)
via 0bd66d4d040fdd5dc3894069720ba338541251cd (commit)
via 5b235b519589b830c55e65b7ff5412ee62028d91 (commit)
via d5d16346758cf28e1f0263e87d56ce75a7913c2a (commit)
via c1e1df42e2821e3713d808c4d2a171d94326d175 (commit)
via 9a90babfa14554d07c43a6d578f1634adb3ae067 (commit)
via d676c7e5b6166d49497aae851eea84037f94b412 (commit)
via eb87192ddcaaed47dd54f95716674502862b3a1d (commit)
via e12e50efaaa2944a7291c4b021aa2891ef80af17 (commit)
via a2ffbdfd1c7948d341a316d153896cfc772955ce (commit)
via 3ea6fadac295600f3d18b9cf66d3f74cb26b333d (commit)
via 54be19e6c8d7bdb5530af2eb597d65802796b555 (commit)
via 46b6b7c9b4dcad989f8451638753594b572f9f9a (commit)
via fa8dfa28d194cae3c72dd18d8f91c7c9ecc33198 (commit)
via 44082f9988c33b6dda519d5cb54d85ee515878b9 (commit)
via f12dee199c5f6207ddddafd26c85136daa6842ad (commit)
via 97cbc1802154bd2f9b1127490d3a4ab0867a214f (commit)
via b34a52e4b97b3606b4d93a6291874620c3e3a676 (commit)
via 94bba97a455fdf22d65bb4e503da0f5a24743dd3 (commit)
via 7cc1f1bfc09653479ae8bb0db0f2ce5a7d19bd0a (commit)
via 90e4976800c18d16c66a72c1d0c23b73ce59d7a2 (commit)
via 6fcb0d498f8f5c39a94a8d0c79e425b480c272bc (commit)
via 77814588a8177735d8552fd3f11a97c0e8250f01 (commit)
via 6ff3238825f21e0abec37b1d485318648d824cab (commit)
via 4fcb6eb3016de68b4a742cd6b4d2248550529deb (commit)
via 96254254a6ed491ebf8826f8e28d40425aa4f2ef (commit)
via 5eb7345cc7d266dbb74534bb7510d428b58ce0a3 (commit)
via df79047cb62c26755f35083557686828849008b3 (commit)
via e275b3175b710d3289e83bf0130bd0504951adc2 (commit)
via 8687265c9a2f26a0ee40f80366d4f17a3d600fac (commit)
via a8ee1c2d63b79672c39a2c40c4067f05b6afb799 (commit)
via 04a515a8ca679844b3aab8d28243d1711693528c (commit)
via 631a3145f87aec6248be77a6fe3e6c263e373c91 (commit)
via 7ef2b8b71179bcc5fe90a673f684fc221f7d28a3 (commit)
via 3523cdc4a441e9fb2d8fcc020b04bd819b3019b8 (commit)
via ef5333672435c094c6088da8052838b43020c66e (commit)
via 7e08cf4352d41c372584db69fc59c928f63c324f (commit)
via 4a24a14b09304272349c83c57b0d202193d30d4d (commit)
via 7a61c957243f8f4fe4d8b89dc19e90aa98e98a25 (commit)
via 5b849b1e22f21cf349bee3103af949f62b344d83 (commit)
via dfc8f5aef4e49a8d23f906b4b36f6c37f07a2dc9 (commit)
via b0974557728a7553ad272040c86ecd81641bdf0f (commit)
via 64bc2a7931606f2165ab513f1d8f129c1f0735b0 (commit)
via a268252629a0f6b31e5f0189454144676dd7ffaa (commit)
via 5c96acd6f119b71fc75e5d48465afca9fd13e87f (commit)
via 9100fcb4095cf8858d4cd2c613bff69ceb4f71ec (commit)
via 83512a6ff529c7c5cb6315167cba1cf132e6a67a (commit)
via 1a8fdb1462f8a506b2043877ab73cb86a9179ca6 (commit)
via 22fd851e1438afba1486f3e7a48e47435e0171f7 (commit)
via c3d3023e4acd8015b3f53c6fb1d55f27417fe8df (commit)
via e4537cb37ed5b075c62723c9a49348c76eeb3d5c (commit)
via bd8991c2f6546d42008ade8dd4db133a120c44db (commit)
via 40cdf498b9153685b4cefe576e59f6b41090912b (commit)
via 8bca6cf28bf5162e0e4bb890c44b1ac1be204400 (commit)
via 05b9baadbc34d9900195caf02c20a8b18f11b3a5 (commit)
via 25963316407ee678c8bcb40f3338029a68fe4b56 (commit)
via 6ce6b62099458c10eab762777e5d812c895df5d4 (commit)
via 39176736b3b67d7ff528500f5e61b9f62c1f3190 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (bae4db1b59737e95bd11c60ca7f0abe7f1b6d994)
\
N -- N -- N (1debcc54c6bc897dc11923734501e4ce23923475)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=1debcc54c6bc897dc11...
commit 1debcc54c6bc897dc11923734501e4ce23923475
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
update content broadcast error handling
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index ec283aa..a398192 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -137,13 +137,13 @@ static bool pdf_convert(struct content *c)
content_data,
content_length);
if (pdfres != NSPDFERROR_OK) {
- content_broadcast_errorcode(c, NSERROR_INVALID);
+ content_broadcast_error(c, NSERROR_INVALID, NULL);
return false;
}
pdfres = nspdf_page_count(pdfc->doc, &pdfc->page_count);
if (pdfres != NSPDFERROR_OK) {
- content_broadcast_errorcode(c, NSERROR_INVALID);
+ content_broadcast_error(c, NSERROR_INVALID, NULL);
return false;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=dd422bb7045f958adb5...
commit dd422bb7045f958adb5bab9786209d6a825f2613
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix plot style float to fix path width
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index 89548cd..ec283aa 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -1,6 +1,5 @@
/*
- * Copyright 2004 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2004 John M Bell <jmb202(a)ecs.soton.ac.uk>
+ * Copyright 2018 Vincent Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -154,7 +153,7 @@ static bool pdf_convert(struct content *c)
}
/** \todo extract documents starting page number */
- pdfc->current_page = 16;
+ pdfc->current_page = 0;
pdfres = nspdf_get_page_dimensions(pdfc->doc,
pdfc->current_page,
@@ -180,12 +179,16 @@ pdf_path(const struct nspdf_style *style,
{
const struct redraw_context *ctx = ctxin;
- ctx->plot->path(ctx,
- (const struct plot_style_s *)style,
- path,
- path_length,
- style->stroke_width,
- transform);
+ struct plot_style_s nsstyle;
+
+ nsstyle.stroke_type = style->stroke_type;
+ nsstyle.stroke_width = plot_style_float_to_fixed(style->stroke_width);
+ nsstyle.stroke_colour = style->stroke_colour;
+ nsstyle.fill_type = style->fill_type;
+ nsstyle.fill_colour = style->fill_colour;
+
+ ctx->plot->path(ctx, &nsstyle, path, path_length, transform);
+
return NSPDFERROR_OK;
}
diff --git a/include/netsurf/plot_style.h b/include/netsurf/plot_style.h
index f1b6172..11d506d 100644
--- a/include/netsurf/plot_style.h
+++ b/include/netsurf/plot_style.h
@@ -50,6 +50,9 @@ typedef int32_t plot_style_fixed;
/* Convert an int to fixed point */
#define plot_style_int_to_fixed(v) ((v) << PLOT_STYLE_RADIX)
+/* Convert an float to fixed point */
+#define plot_style_float_to_fixed(v) ((v) * (1<<PLOT_STYLE_RADIX))
+
/* Convert fixed point to int */
#define plot_style_fixed_to_int(v) ((v) >> PLOT_STYLE_RADIX)
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=f819d17bb20ccdb7430...
commit f819d17bb20ccdb7430deb56ebd3722cfbd3148b
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
allow moving forward and back clicking in window
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index d8c4d61..89548cd 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -33,8 +33,10 @@
#include "utils/messages.h"
#include "utils/utils.h"
+#include "utils/log.h"
#include "netsurf/plotters.h"
#include "netsurf/content.h"
+#include "netsurf/browser_window.h"
#include "content/llcache.h"
#include "content/content_protected.h"
@@ -46,6 +48,7 @@ typedef struct pdf_content {
struct nspdf_doc *doc;
unsigned int current_page;
+ unsigned int page_count;
} pdf_content;
static nserror nspdf2nserr(nspdferror nspdferr)
@@ -139,13 +142,19 @@ static bool pdf_convert(struct content *c)
return false;
}
+ pdfres = nspdf_page_count(pdfc->doc, &pdfc->page_count);
+ if (pdfres != NSPDFERROR_OK) {
+ content_broadcast_errorcode(c, NSERROR_INVALID);
+ return false;
+ }
+
pdfres = nspdf_get_title(pdfc->doc, &title);
if (pdfres == NSPDFERROR_OK) {
content__set_title(c, lwc_string_data(title));
}
/** \todo extract documents starting page number */
- pdfc->current_page = 0;
+ pdfc->current_page = 16;
pdfres = nspdf_get_page_dimensions(pdfc->doc,
pdfc->current_page,
@@ -172,7 +181,7 @@ pdf_path(const struct nspdf_style *style,
const struct redraw_context *ctx = ctxin;
ctx->plot->path(ctx,
- style,
+ (const struct plot_style_s *)style,
path,
path_length,
style->stroke_width,
@@ -191,7 +200,8 @@ pdf_redraw(struct content *c,
nspdferror pdfres;
struct nspdf_render_ctx render_ctx;
- printf("data x:%d y:%d w:%d h:%d\nclip %d %d %d %d\n",
+ NSLOG(netsurf, DEBUG,
+ "data x:%d y:%d w:%d h:%d\nclip %d %d %d %d\n",
data->x, data->y, data->width, data->height,
clip->x0, clip->y0, clip->x1, clip->y1);
@@ -206,7 +216,6 @@ pdf_redraw(struct content *c,
pdfres = nspdf_page_render(pdfc->doc, pdfc->current_page, &render_ctx);
-
return true;
}
@@ -224,32 +233,56 @@ static content_type pdf_content_type(void)
}
static void
+pdf_change_page(struct pdf_content *pdfc,
+ struct browser_window *bw,
+ unsigned int page_number)
+{
+ float page_width;
+ float page_height;
+ nspdferror pdfres;
+
+ /* ensure page stays in bounds */
+ if (page_number >= pdfc->page_count) {
+ return;
+ }
+
+ pdfc->current_page = page_number;
+
+ pdfres = nspdf_get_page_dimensions(pdfc->doc,
+ pdfc->current_page,
+ &page_width,
+ &page_height);
+ if (pdfres == NSPDFERROR_OK) {
+ pdfc->base.width = page_width;
+ pdfc->base.height = page_height;
+ NSLOG(netsurf, DEBUG,
+ "page %d w:%f h:%f\n",
+ pdfc->current_page,
+ page_width,
+ page_height);
+ }
+
+ browser_window_update(bw, false);
+}
+
+static void
pdf_mouse_action(struct content *c,
struct browser_window *bw,
browser_mouse_state mouse,
int x, int y)
{
struct pdf_content *pdfc = (struct pdf_content *)c;
- nspdferror pdfres;
- printf("ici\n");
+
if (mouse & BROWSER_MOUSE_CLICK_1) {
- float page_width;
- float page_height;
-
- pdfc->current_page++;
-
- pdfres = nspdf_get_page_dimensions(pdfc->doc,
- pdfc->current_page,
- &page_width,
- &page_height);
- if (pdfres == NSPDFERROR_OK) {
- pdfc->base.width = page_width;
- pdfc->base.height = page_height;
- printf("page $d w:%f h:%f\n",pdfc->current_page, page_width, page_height);
+ int bwwidth;
+ int bwheight;
+ browser_window_get_extents(bw, false, &bwwidth, &bwheight);
+
+ if (x < (bwwidth / 2)) {
+ pdf_change_page(pdfc, bw, pdfc->current_page - 1);
+ } else {
+ pdf_change_page(pdfc, bw, pdfc->current_page + 1);
}
-
- browser_window_update(bw, false);
-
}
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=c3a96c0797caca6a9bf...
commit c3a96c0797caca6a9bf905697d7a27dc461bf036
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
allow clicking to change page
diff --git a/content/content.c b/content/content.c
index 385847d..5cd3b45 100644
--- a/content/content.c
+++ b/content/content.c
@@ -571,7 +571,7 @@ bool content_exec(struct hlcache_handle *h, const char *src, size_t srclen)
return c->handler->exec(c, src, srclen);
}
-/* exported interface, documented in content/content.h */
+/* exported interface, documented in content/content_protected.h */
bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
const struct rect *clip, const struct redraw_context *ctx)
{
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index d62f1ff..d8c4d61 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -31,7 +31,10 @@
#include <nspdf/meta.h>
#include <nspdf/page.h>
+#include "utils/messages.h"
#include "utils/utils.h"
+#include "netsurf/plotters.h"
+#include "netsurf/content.h"
#include "content/llcache.h"
#include "content/content_protected.h"
@@ -41,6 +44,8 @@ typedef struct pdf_content {
struct content base;
struct nspdf_doc *doc;
+
+ unsigned int current_page;
} pdf_content;
static nserror nspdf2nserr(nspdferror nspdferr)
@@ -120,6 +125,8 @@ static bool pdf_convert(struct content *c)
const uint8_t *content_data;
unsigned long content_length;
struct lwc_string_s *title;
+ float page_width;
+ float page_height;
content_data = (const uint8_t *)content__get_source_data(c,
&content_length);
@@ -137,6 +144,18 @@ static bool pdf_convert(struct content *c)
content__set_title(c, lwc_string_data(title));
}
+ /** \todo extract documents starting page number */
+ pdfc->current_page = 0;
+
+ pdfres = nspdf_get_page_dimensions(pdfc->doc,
+ pdfc->current_page,
+ &page_width,
+ &page_height);
+ if (pdfres == NSPDFERROR_OK) {
+ pdfc->base.width = page_width;
+ pdfc->base.height = page_height;
+ }
+
content_set_ready(c);
content_set_done(c);
@@ -145,11 +164,19 @@ static bool pdf_convert(struct content *c)
static nspdferror
pdf_path(const struct nspdf_style *style,
- const float *p,
- unsigned int n,
+ const float *path,
+ unsigned int path_length,
const float transform[6],
- const void *ctx)
+ const void *ctxin)
{
+ const struct redraw_context *ctx = ctxin;
+
+ ctx->plot->path(ctx,
+ style,
+ path,
+ path_length,
+ style->stroke_width,
+ transform);
return NSPDFERROR_OK;
}
@@ -164,16 +191,20 @@ pdf_redraw(struct content *c,
nspdferror pdfres;
struct nspdf_render_ctx render_ctx;
+ printf("data x:%d y:%d w:%d h:%d\nclip %d %d %d %d\n",
+ data->x, data->y, data->width, data->height,
+ clip->x0, clip->y0, clip->x1, clip->y1);
+
render_ctx.ctx = ctx;
- render_ctx.device_space[0] = 1;
+ render_ctx.device_space[0] = 1; /* scale x */
render_ctx.device_space[1] = 0;
render_ctx.device_space[2] = 0;
- render_ctx.device_space[3] = 1;
+ render_ctx.device_space[3] = -1; /* scale y */
render_ctx.device_space[4] = 0; /* x offset */
- render_ctx.device_space[5] = -200; /* y offset */
+ render_ctx.device_space[5] = data->height; /* y offset */
render_ctx.path = pdf_path;
- pdfres = nspdf_page_render(pdfc->doc, 0, &render_ctx);
+ pdfres = nspdf_page_render(pdfc->doc, pdfc->current_page, &render_ctx);
return true;
@@ -192,12 +223,42 @@ static content_type pdf_content_type(void)
return CONTENT_PDF;
}
+static void
+pdf_mouse_action(struct content *c,
+ struct browser_window *bw,
+ browser_mouse_state mouse,
+ int x, int y)
+{
+ struct pdf_content *pdfc = (struct pdf_content *)c;
+ nspdferror pdfres;
+ printf("ici\n");
+ if (mouse & BROWSER_MOUSE_CLICK_1) {
+ float page_width;
+ float page_height;
+
+ pdfc->current_page++;
+
+ pdfres = nspdf_get_page_dimensions(pdfc->doc,
+ pdfc->current_page,
+ &page_width,
+ &page_height);
+ if (pdfres == NSPDFERROR_OK) {
+ pdfc->base.width = page_width;
+ pdfc->base.height = page_height;
+ printf("page $d w:%f h:%f\n",pdfc->current_page, page_width, page_height);
+ }
+
+ browser_window_update(bw, false);
+
+ }
+}
static const content_handler nspdf_content_handler = {
.create = pdf_create,
.data_complete = pdf_convert,
.destroy = pdf_destroy,
.redraw = pdf_redraw,
+ .mouse_action = pdf_mouse_action,
.clone = pdf_clone,
.type = pdf_content_type,
.no_share = false,
diff --git a/desktop/browser_window.c b/desktop/browser_window.c
index f43e93e..e23d769 100644
--- a/desktop/browser_window.c
+++ b/desktop/browser_window.c
@@ -2021,6 +2021,7 @@ browser_window_mouse_click_internal(struct browser_window *bw,
switch (content_get_type(c)) {
case CONTENT_HTML:
+ case CONTENT_PDF:
case CONTENT_TEXTPLAIN:
{
/* Give bw focus */
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=2b6659f4adc97bbcfc4...
commit 2b6659f4adc97bbcfc4488c3ce65da36a195712a
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
call page render interface
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index 288aa58..d62f1ff 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -29,6 +29,7 @@
#include <nspdf/document.h>
#include <nspdf/meta.h>
+#include <nspdf/page.h>
#include "utils/utils.h"
#include "content/llcache.h"
@@ -142,6 +143,16 @@ static bool pdf_convert(struct content *c)
return true;
}
+static nspdferror
+pdf_path(const struct nspdf_style *style,
+ const float *p,
+ unsigned int n,
+ const float transform[6],
+ const void *ctx)
+{
+ return NSPDFERROR_OK;
+}
+
/* exported interface documented in image_cache.h */
static bool
pdf_redraw(struct content *c,
@@ -149,6 +160,22 @@ pdf_redraw(struct content *c,
const struct rect *clip,
const struct redraw_context *ctx)
{
+ struct pdf_content *pdfc = (struct pdf_content *)c;
+ nspdferror pdfres;
+ struct nspdf_render_ctx render_ctx;
+
+ render_ctx.ctx = ctx;
+ render_ctx.device_space[0] = 1;
+ render_ctx.device_space[1] = 0;
+ render_ctx.device_space[2] = 0;
+ render_ctx.device_space[3] = 1;
+ render_ctx.device_space[4] = 0; /* x offset */
+ render_ctx.device_space[5] = -200; /* y offset */
+ render_ctx.path = pdf_path;
+
+ pdfres = nspdf_page_render(pdfc->doc, 0, &render_ctx);
+
+
return true;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=f7e377dc5383097fd30...
commit f7e377dc5383097fd301d67858c2b9f0a95defdf
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
set the pdf title if available
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index 657a5e9..288aa58 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <nspdf/document.h>
+#include <nspdf/meta.h>
#include "utils/utils.h"
#include "content/llcache.h"
@@ -117,6 +118,7 @@ static bool pdf_convert(struct content *c)
nspdferror pdfres;
const uint8_t *content_data;
unsigned long content_length;
+ struct lwc_string_s *title;
content_data = (const uint8_t *)content__get_source_data(c,
&content_length);
@@ -129,8 +131,14 @@ static bool pdf_convert(struct content *c)
return false;
}
+ pdfres = nspdf_get_title(pdfc->doc, &title);
+ if (pdfres == NSPDFERROR_OK) {
+ content__set_title(c, lwc_string_data(title));
+ }
+
content_set_ready(c);
content_set_done(c);
+
return true;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=8ca79d6013ae99f37b4...
commit 8ca79d6013ae99f37b4be94a3390f5be34a02477
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
use nspdf library to parse document
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
index 23457a2..657a5e9 100644
--- a/content/handlers/pdf/pdf.c
+++ b/content/handlers/pdf/pdf.c
@@ -27,12 +27,39 @@
#include <stdbool.h>
#include <stdlib.h>
+#include <nspdf/document.h>
+
#include "utils/utils.h"
#include "content/llcache.h"
#include "content/content_protected.h"
#include "pdf.h"
+typedef struct pdf_content {
+ struct content base;
+
+ struct nspdf_doc *doc;
+} pdf_content;
+
+static nserror nspdf2nserr(nspdferror nspdferr)
+{
+ nserror res;
+ switch (nspdferr) {
+ case NSPDFERROR_OK:
+ res = NSERROR_OK;
+ break;
+
+ case NSPDFERROR_NOMEM:
+ res = NSERROR_NOMEM;
+ break;
+
+ default:
+ res = NSERROR_UNKNOWN;
+ break;
+ }
+ return res;
+}
+
/**
* Content create entry point.
*/
@@ -45,32 +72,63 @@ pdf_create(const content_handler *handler,
bool quirks,
struct content **c)
{
- struct content *jpeg;
- nserror error;
+ struct pdf_content *pdfc;
+ nserror res;
+ nspdferror pdfres;
- jpeg = calloc(1, sizeof(struct content));
- if (jpeg == NULL)
+ pdfc = calloc(1, sizeof(struct pdf_content));
+ if (pdfc == NULL) {
return NSERROR_NOMEM;
+ }
+
+ res = content__init(&pdfc->base,
+ handler,
+ imime_type,
+ params,
+ llcache,
+ fallback_charset,
+ quirks);
+ if (res != NSERROR_OK) {
+ free(pdfc);
+ return res;
+ }
- error = content__init(jpeg, handler, imime_type, params,
- llcache, fallback_charset, quirks);
- if (error != NSERROR_OK) {
- free(jpeg);
- return error;
+ pdfres = nspdf_document_create(&pdfc->doc);
+ if (pdfres != NSPDFERROR_OK) {
+ free(pdfc);
+ return nspdf2nserr(res);
}
- *c = jpeg;
+ *c = (struct content *)pdfc;
return NSERROR_OK;
}
/* exported interface documented in image_cache.h */
-static void pdf_destroy(struct content *content)
+static void pdf_destroy(struct content *c)
{
+ struct pdf_content *pdfc = (struct pdf_content *)c;
+ nspdf_document_destroy(pdfc->doc);
}
static bool pdf_convert(struct content *c)
{
+ struct pdf_content *pdfc = (struct pdf_content *)c;
+ nspdferror pdfres;
+ const uint8_t *content_data;
+ unsigned long content_length;
+
+ content_data = (const uint8_t *)content__get_source_data(c,
+ &content_length);
+
+ pdfres = nspdf_document_parse(pdfc->doc,
+ content_data,
+ content_length);
+ if (pdfres != NSPDFERROR_OK) {
+ content_broadcast_errorcode(c, NSERROR_INVALID);
+ return false;
+ }
+
content_set_ready(c);
content_set_done(c);
return true;
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=ca40e217685d04f8345...
commit ca40e217685d04f83459645a660c891a18b01def
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Add initial content handler for PDF format
diff --git a/Makefile b/Makefile
index b2e89ac..8784a46 100644
--- a/Makefile
+++ b/Makefile
@@ -520,7 +520,6 @@ include Makefile.defaults
# libraries enabled by feature switch without pkgconfig file
$(eval $(call feature_switch,JPEG,JPEG (libjpeg),-DWITH_JPEG,-ljpeg,-UWITH_JPEG,))
-$(eval $(call feature_switch,HARU_PDF,PDF export (haru),-DWITH_PDF_EXPORT,-lhpdf -lpng,-UWITH_PDF_EXPORT,))
$(eval $(call feature_switch,LIBICONV_PLUG,glibc internal iconv,-DLIBICONV_PLUG,,-ULIBICONV_PLUG,-liconv))
$(eval $(call feature_switch,DUKTAPE,Javascript (Duktape),,,,,))
@@ -562,6 +561,7 @@ $(eval $(call pkg_config_find_and_add_enabled,NSSVG,libsvgtiny,SVG))
$(eval $(call pkg_config_find_and_add_enabled,ROSPRITE,librosprite,Sprite))
$(eval $(call pkg_config_find_and_add_enabled,NSPSL,libnspsl,PSL))
$(eval $(call pkg_config_find_and_add_enabled,NSLOG,libnslog,LOG))
+$(eval $(call pkg_config_find_and_add_enabled,NSPDF,libnspdf,PDF))
# List of directories in which headers are searched for
INCLUDE_DIRS :=. include $(OBJROOT)
diff --git a/Makefile.defaults b/Makefile.defaults
index 12c83a1..696430d 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -67,11 +67,9 @@ NETSURF_USE_WEBP := AUTO
# Valid options: YES, NO
NETSURF_USE_DUKTAPE := YES
-# Enable NetSurf's use of libharu for PDF export and GTK printing support.
-# There is no auto-detection available for this, as it does not have a
-# pkg-config file.
-# Valid options: YES, NO
-NETSURF_USE_HARU_PDF := NO
+# Enable the use of netsurf integrated pdf viewing
+# Valid options: YES, NO, AUTO
+NETSURF_USE_NSPDF := AUTO
# Enable the use of the Public suffix library to detect supercookies
# Valid options: YES, NO, AUTO (highly recommended)
diff --git a/content/content_protected.h b/content/content_protected.h
index f0a95b6..fb3639c 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -37,17 +37,34 @@ struct content_redraw_data;
struct http_parameter;
struct content_handler {
+ /**
+ * content handler finalisation
+ */
void (*fini)(void);
+ /**
+ * create a content
+ */
nserror (*create)(const struct content_handler *handler,
lwc_string *imime_type,
const struct http_parameter *params,
struct llcache_handle *llcache,
- const char *fallback_charset, bool quirks,
+ const char *fallback_charset,
+ bool quirks,
struct content **c);
+ /**
+ * ongoing fetch has received data
+ */
bool (*process_data)(struct content *c,
- const char *data, unsigned int size);
+ const char *data,
+ unsigned int size);
+
+ /**
+ * fetcher has completed retrieving all the data
+ *
+ * \param c The completed content.
+ */
bool (*data_complete)(struct content *c);
void (*reformat)(struct content *c, int width, int height);
void (*destroy)(struct content *c);
@@ -84,10 +101,14 @@ struct content_handler {
void (*remove_user)(struct content *c);
bool (*exec)(struct content *c, const char *src, size_t srclen);
- /** handler dependant content sensitive internal data interface. */
+ /**
+ * handler dependant content sensitive internal data interface.
+ */
void * (*get_internal)(const struct content *c, void *context);
- /** There must be one content per user for this type. */
+ /**
+ * There must be one content per user for this type.
+ */
bool no_share;
};
diff --git a/content/handlers/Makefile b/content/handlers/Makefile
index ea9d0c8..b88f3ca 100644
--- a/content/handlers/Makefile
+++ b/content/handlers/Makefile
@@ -23,5 +23,10 @@ include content/handlers/text/Makefile
S_CONTENT += $(addprefix handlers/text/,$(S_TEXT))
+# PDF content handler source
+include content/handlers/pdf/Makefile
+
+S_CONTENT += $(addprefix handlers/pdf/,$(S_PDF))
+
# extend the include search path
INCLUDE_DIRS += content/handlers
diff --git a/content/handlers/image/jpeg.c b/content/handlers/image/jpeg.c
index 9df084b..8689acb 100644
--- a/content/handlers/image/jpeg.c
+++ b/content/handlers/image/jpeg.c
@@ -19,7 +19,7 @@
/**
* \file
- * implementation of content handling for image/jpeg
+ * implementation of content handling for JPEG images.
*
* This implementation uses the IJG JPEG library.
*/
diff --git a/content/handlers/pdf/Makefile b/content/handlers/pdf/Makefile
new file mode 100644
index 0000000..32d6e27
--- /dev/null
+++ b/content/handlers/pdf/Makefile
@@ -0,0 +1,11 @@
+#
+# NetSurf pdf source file inclusion
+#
+# Included by content handlers Makefile
+#
+
+ifeq ($(NETSURF_USE_NSPDF),YES)
+S_PDF := pdf.c
+else
+S_PDF :=
+endif
diff --git a/content/handlers/pdf/pdf.c b/content/handlers/pdf/pdf.c
new file mode 100644
index 0000000..23457a2
--- /dev/null
+++ b/content/handlers/pdf/pdf.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2004 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2004 John M Bell <jmb202(a)ecs.soton.ac.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * implementation of content handling for PDF.
+ *
+ * This implementation uses the netsurf pdf library.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "utils/utils.h"
+#include "content/llcache.h"
+#include "content/content_protected.h"
+
+#include "pdf.h"
+
+/**
+ * Content create entry point.
+ */
+static nserror
+pdf_create(const content_handler *handler,
+ lwc_string *imime_type,
+ const struct http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset,
+ bool quirks,
+ struct content **c)
+{
+ struct content *jpeg;
+ nserror error;
+
+ jpeg = calloc(1, sizeof(struct content));
+ if (jpeg == NULL)
+ return NSERROR_NOMEM;
+
+ error = content__init(jpeg, handler, imime_type, params,
+ llcache, fallback_charset, quirks);
+ if (error != NSERROR_OK) {
+ free(jpeg);
+ return error;
+ }
+
+ *c = jpeg;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in image_cache.h */
+static void pdf_destroy(struct content *content)
+{
+}
+
+static bool pdf_convert(struct content *c)
+{
+ content_set_ready(c);
+ content_set_done(c);
+ return true;
+}
+
+/* exported interface documented in image_cache.h */
+static bool
+pdf_redraw(struct content *c,
+ struct content_redraw_data *data,
+ const struct rect *clip,
+ const struct redraw_context *ctx)
+{
+ return true;
+}
+
+/**
+ * Clone content.
+ */
+static nserror pdf_clone(const struct content *old, struct content **newc)
+{
+ return NSERROR_NOMEM;
+}
+
+static content_type pdf_content_type(void)
+{
+ return CONTENT_PDF;
+}
+
+
+static const content_handler nspdf_content_handler = {
+ .create = pdf_create,
+ .data_complete = pdf_convert,
+ .destroy = pdf_destroy,
+ .redraw = pdf_redraw,
+ .clone = pdf_clone,
+ .type = pdf_content_type,
+ .no_share = false,
+};
+
+static const char *nspdf_types[] = {
+ "application/pdf",
+ "application/x-pdf",
+ "application/acrobat",
+ "applications/vnd.pdf",
+ "text/pdf",
+ "text/x-pdf"
+};
+
+CONTENT_FACTORY_REGISTER_TYPES(nspdf, nspdf_types, nspdf_content_handler);
diff --git a/content/handlers/pdf/pdf.h b/content/handlers/pdf/pdf.h
new file mode 100644
index 0000000..2171b80
--- /dev/null
+++ b/content/handlers/pdf/pdf.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Interface for PDF content handler.
+ */
+
+#ifndef NETSURF_PDF_PDF_H_
+#define NETSURF_PDF_PDF_H_
+
+nserror nspdf_init(void);
+
+#endif
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index e3babd8..8a0f24e 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -46,6 +46,7 @@
#include "javascript/js.h"
#include "html/html.h"
#include "text/textplain.h"
+#include "pdf/pdf.h"
#include "netsurf/browser_window.h"
#include "desktop/system_colour.h"
@@ -187,6 +188,12 @@ nserror netsurf_init(const char *store_path)
if (ret != NSERROR_OK)
return ret;
+#ifdef WITH_NSPDF
+ ret = nspdf_init();
+ if (ret != NSERROR_OK)
+ return ret;
+#endif
+
setlocale(LC_ALL, "");
/* initialise the fetchers */
diff --git a/include/netsurf/content_type.h b/include/netsurf/content_type.h
index ef654cd..155db1f 100644
--- a/include/netsurf/content_type.h
+++ b/include/netsurf/content_type.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2003 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2012 Vincent Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -68,8 +68,11 @@ typedef enum {
/** All script types. */
CONTENT_SCRIPT = 0x40,
+ /** Portable Document Format. */
+ CONTENT_PDF = 0x80,
+
/** Any content matches */
- CONTENT_ANY = 0x7f
+ CONTENT_ANY = 0xff
} content_type;
-----------------------------------------------------------------------
Summary of changes:
.gitignore | 3 +-
Makefile | 24 +-
Makefile.config.example | 10 +
Makefile.defaults | 8 +-
content/content.c | 147 +-
content/content.h | 55 +-
content/content_factory.c | 5 +-
content/content_protected.h | 20 +-
content/fetch.c | 54 +
content/fetch.h | 52 +-
content/fetchers/about.c | 993 +-
content/fetchers/curl.c | 417 +-
content/fetchers/data.c | 40 +-
content/handlers/css/css.c | 29 +-
content/handlers/css/css.h | 1 -
content/handlers/css/hints.c | 120 +-
content/handlers/css/select.c | 2 +-
content/handlers/css/select.h | 2 +-
content/handlers/css/utils.c | 38 +-
content/handlers/css/utils.h | 28 +
content/handlers/html/box.c | 10 +-
content/handlers/html/box.h | 11 +-
content/handlers/html/box_construct.c | 97 +-
content/handlers/html/box_textarea.c | 17 +-
content/handlers/html/form.c | 1734 ++-
content/handlers/html/form_internal.h | 52 +-
content/handlers/html/html.c | 362 +-
content/handlers/html/html_css.c | 20 +-
content/handlers/html/html_forms.c | 11 +
content/handlers/html/html_interaction.c | 82 +-
content/handlers/html/html_internal.h | 13 +-
content/handlers/html/html_object.c | 29 +-
content/handlers/html/html_redraw.c | 4 +-
content/handlers/html/html_script.c | 102 +-
content/handlers/html/imagemap.c | 8 +-
content/handlers/html/layout.c | 9 +
content/handlers/html/search.c | 106 +-
content/handlers/html/search.h | 5 -
content/handlers/image/Makefile | 4 +-
content/handlers/image/bmp.c | 10 +-
content/handlers/image/gif.c | 10 +-
content/handlers/image/ico.c | 10 +-
content/handlers/image/image.c | 7 +
content/handlers/image/jpeg.c | 16 +-
content/handlers/image/nssprite.c | 10 +-
content/handlers/image/png.c | 18 +-
content/handlers/image/rsvg.c | 18 +-
content/handlers/image/svg.c | 21 +-
content/handlers/image/webp.c | 232 +
content/handlers/{pdf/pdf.h => image/webp.h} | 10 +-
content/handlers/javascript/content.c | 5 +-
content/handlers/javascript/duktape/Console.bnd | 50 +-
content/handlers/javascript/duktape/Document.bnd | 121 +-
content/handlers/javascript/duktape/Element.bnd | 14 +
content/handlers/javascript/duktape/Event.bnd | 41 +
.../javascript/duktape/HTMLBodyElement.bnd | 33 +
.../javascript/duktape/HTMLFrameSetElement.bnd | 34 +
content/handlers/javascript/duktape/Makefile | 31 +-
content/handlers/javascript/duktape/Node.bnd | 9 +
content/handlers/javascript/duktape/Window.bnd | 559 +-
content/handlers/javascript/duktape/duk_config.h | 126 +-
content/handlers/javascript/duktape/duk_custom.h | 2 +
content/handlers/javascript/duktape/dukky.c | 374 +-
content/handlers/javascript/duktape/dukky.h | 18 +-
content/handlers/javascript/duktape/duktape.c |15654 +++++++++++---------
content/handlers/javascript/duktape/duktape.h | 28 +-
content/handlers/javascript/duktape/generics.js | 106 +
content/handlers/javascript/duktape/polyfill.js | 85 +
content/handlers/javascript/js.h | 49 +-
content/handlers/javascript/none/none.c | 2 +-
content/handlers/pdf/pdf.c | 4 +-
content/handlers/text/textplain.c | 20 +-
content/hlcache.c | 59 +-
content/hlcache.h | 5 +-
content/llcache.c | 222 +-
content/llcache.h | 105 +-
content/urldb.c | 7 +-
desktop/Makefile | 3 +-
desktop/browser.c | 3380 +----
desktop/browser_history.c | 82 +-
desktop/browser_history.h | 11 +
desktop/browser_private.h | 80 +-
desktop/{browser.c => browser_window.c} | 6008 +++++---
desktop/cw_helper.c | 92 +
.../riscos/local_history.h => desktop/cw_helper.h | 35 +-
desktop/download.c | 6 +-
desktop/frames.c | 4 +-
desktop/gui_factory.c | 68 +-
desktop/local_history.c | 215 +-
desktop/local_history.h | 7 +
desktop/netsurf.c | 243 +-
desktop/options.h | 4 +-
desktop/save_complete.c | 65 +-
desktop/search.c | 5 +-
desktop/searchweb.c | 45 +-
desktop/searchweb.h | 11 +
desktop/selection.c | 5 +-
desktop/sslcert_viewer.c | 12 +-
desktop/sslcert_viewer.h | 5 +-
desktop/textinput.c | 8 +-
desktop/treeview.c | 116 +-
desktop/version.c | 6 +-
docs/Doxyfile | 2 +-
docs/UnimplementedJavascript.md | 1591 ++
docs/UnimplementedJavascript.txt | 1798 ---
docs/building-GTK.md | 316 +-
docs/env.sh | 9 +-
docs/gource.sh | 4 +-
docs/jsbinding.md | 313 +
docs/mainpage.md | 141 +-
docs/using-monkey.md | 128 +-
frontends/amiga/Makefile | 13 +-
frontends/amiga/Makefile.defaults | 16 +-
frontends/amiga/arexx.c | 120 +-
frontends/amiga/bitmap.c | 28 +-
frontends/amiga/clipboard.c | 65 +-
frontends/amiga/cookies.c | 4 +-
frontends/amiga/corewindow.c | 60 +-
frontends/amiga/ctxmenu.c | 84 +-
frontends/amiga/ctxmenu.h | 7 +-
frontends/amiga/download.c | 64 +-
frontends/amiga/drag.c | 61 +-
frontends/amiga/drag.h | 3 -
frontends/amiga/dt_anim.c | 9 +-
frontends/amiga/dt_picture.c | 15 +-
frontends/amiga/dt_sound.c | 6 +-
frontends/amiga/file.c | 34 +-
frontends/amiga/font.c | 2 +-
frontends/amiga/font_bullet.c | 8 +-
frontends/amiga/font_scan.c | 2 +-
frontends/amiga/gui.c | 960 +-
frontends/amiga/gui.h | 328 +-
frontends/amiga/gui_menu.c | 166 +-
frontends/amiga/gui_menu.h | 6 +
frontends/amiga/gui_options.c | 15 +-
frontends/amiga/history.c | 10 +-
frontends/amiga/history_local.c | 27 +-
frontends/amiga/history_local.h | 4 +-
frontends/amiga/hotlist.c | 10 +-
frontends/amiga/icon.c | 12 +-
frontends/amiga/iff_dr2d.c | 21 +-
frontends/amiga/launch.c | 2 +-
frontends/amiga/libs.c | 28 +-
frontends/amiga/libs.h | 1 +
frontends/amiga/login.c | 285 -
frontends/amiga/login.h | 33 -
frontends/amiga/menu.c | 3 +-
frontends/amiga/misc.c | 14 +-
frontends/amiga/options.h | 3 +-
frontends/amiga/os3support.h | 8 +
frontends/amiga/pkg/netsurf_os3.readme | 2 +-
frontends/amiga/plotters.c | 28 +-
frontends/amiga/print.c | 67 +-
frontends/amiga/schedule.c | 34 +-
frontends/amiga/search.c | 165 +-
frontends/amiga/search.h | 2 +-
frontends/amiga/selectmenu.c | 12 +-
frontends/amiga/sslcert.c | 3 +-
frontends/amiga/stringview/stringview.h | 4 +-
frontends/amiga/theme.c | 63 +-
frontends/amiga/theme.h | 2 -
frontends/amiga/version.c | 2 +-
frontends/atari/Makefile | 28 +-
frontends/atari/bitmap.h | 2 +-
frontends/atari/deskmenu.c | 8 +-
frontends/atari/encoding.h | 2 +-
frontends/atari/file.h | 2 +-
frontends/atari/font.h | 2 +-
frontends/atari/gui.c | 83 +-
frontends/atari/gui.h | 1 -
frontends/atari/login.c | 72 -
frontends/atari/login.h | 26 -
frontends/atari/rootwin.c | 2 -
frontends/atari/search.h | 2 +-
frontends/atari/treeview.c | 32 +-
frontends/beos/gui.cpp | 14 +-
frontends/beos/window.cpp | 85 +-
frontends/beos/window.h | 2 -
frontends/framebuffer/Makefile | 102 +-
frontends/framebuffer/Makefile.defaults | 4 +-
frontends/framebuffer/corewindow.c | 29 +-
frontends/framebuffer/fetch.h | 2 +-
frontends/framebuffer/findfile.c | 109 +-
frontends/framebuffer/findfile.h | 2 +-
frontends/framebuffer/font_freetype.c | 2 +-
frontends/framebuffer/gui.c | 112 +-
frontends/framebuffer/local_history.c | 1 +
frontends/{gtk => framebuffer}/res/Messages | 0
.../{beos => framebuffer}/res/de/welcome.html | 0
.../{beos => framebuffer}/res/en/credits.html | 0
.../{beos => framebuffer}/res/en/licence.html | 0
frontends/{beos => framebuffer}/res/en/maps.html | 0
.../{beos => framebuffer}/res/en/welcome.html | 0
.../{beos => framebuffer}/res/it/credits.html | 0
.../{beos => framebuffer}/res/it/licence.html | 0
.../{beos => framebuffer}/res/ja/welcome.html | 0
frontends/{gtk => framebuffer}/res/nl/credits.html | 0
frontends/{gtk => framebuffer}/res/nl/licence.html | 0
frontends/{gtk => framebuffer}/res/nl/welcome.html | 0
frontends/gtk/Makefile | 7 +-
frontends/gtk/compat.c | 16 +-
frontends/gtk/compat.h | 22 +-
frontends/gtk/completion.c | 50 +-
frontends/gtk/completion.h | 9 +-
frontends/gtk/corewindow.c | 64 +-
frontends/gtk/download.c | 55 +-
frontends/gtk/download.h | 2 +-
frontends/gtk/fetch.c | 10 +-
frontends/gtk/fetch.h | 2 +-
frontends/gtk/gdk.c | 3 +-
frontends/gtk/gui.c | 100 +-
frontends/gtk/gui.h | 3 -
frontends/gtk/local_history.c | 2 +
frontends/gtk/login.c | 285 -
frontends/gtk/login.h | 36 -
frontends/gtk/menu.c | 158 +-
frontends/gtk/menu.h | 181 +-
frontends/gtk/options.h | 9 +-
frontends/gtk/preferences.c | 30 +-
frontends/gtk/res/login.gtk2.ui | 162 -
frontends/gtk/res/login.gtk3.ui | 161 -
frontends/gtk/res/netsurf.gresource.xml | 5 +-
frontends/gtk/res/netsurf.gtk2.ui | 154 +-
frontends/gtk/res/netsurf.gtk3.ui | 156 +-
frontends/gtk/res/tabcontents.gtk2.ui | 165 +-
frontends/gtk/res/tabcontents.gtk3.ui | 223 +-
frontends/gtk/res/toolbar.gtk2.ui | 214 +-
frontends/gtk/res/toolbar.gtk3.ui | 181 +-
frontends/gtk/resources.c | 4 +-
frontends/gtk/scaffolding.c | 3040 ++--
frontends/gtk/scaffolding.h | 163 +-
frontends/gtk/schedule.c | 52 +-
frontends/gtk/search.c | 415 +-
frontends/gtk/search.h | 49 +-
frontends/gtk/selection.c | 1 +
frontends/gtk/selection.h | 2 +-
frontends/gtk/tabs.c | 313 +-
frontends/gtk/tabs.h | 48 +-
frontends/gtk/throbber.c | 48 +-
frontends/gtk/throbber.h | 33 +-
frontends/gtk/toolbar.c | 4515 ++++--
frontends/gtk/toolbar.h | 156 +-
frontends/gtk/toolbar_items.h | 159 +
frontends/gtk/viewsource.c | 9 +-
frontends/gtk/window.c | 522 +-
frontends/gtk/window.h | 90 +-
frontends/monkey/401login.c | 209 +-
frontends/monkey/401login.h | 42 +-
frontends/monkey/Makefile | 34 +-
frontends/monkey/bitmap.c | 3 +-
frontends/monkey/browser.c | 360 +-
frontends/monkey/cert.c | 126 +-
frontends/monkey/cert.h | 7 +-
frontends/monkey/dispatch.c | 13 +-
frontends/monkey/dispatch.h | 2 +
frontends/monkey/download.c | 13 +-
frontends/monkey/farmer.py | 363 -
frontends/monkey/fetch.h | 2 +-
frontends/monkey/filetype.c | 9 +-
frontends/monkey/main.c | 43 +-
frontends/{riscos/assert.c => monkey/output.c} | 48 +-
.../pdf/pdf.h => frontends/monkey/output.h | 21 +-
frontends/monkey/plot.c | 36 +-
frontends/monkey/schedule.c | 10 +-
frontends/riscos/401login.c | 235 -
frontends/riscos/Makefile | 2 +-
frontends/riscos/bitmap.h | 2 +-
frontends/riscos/content-handlers/artworks.c | 53 +-
frontends/riscos/content-handlers/draw.c | 11 +-
frontends/riscos/content-handlers/sprite.c | 13 +-
frontends/riscos/corewindow.c | 75 +-
frontends/riscos/dialog.c | 4 -
frontends/riscos/font.h | 2 +-
frontends/riscos/gui.c | 6 +-
frontends/riscos/gui.h | 13 +-
frontends/riscos/local_history.c | 11 +
frontends/riscos/save.c | 8 +-
frontends/riscos/sslcert.c | 1 +
frontends/riscos/templates/de | 118 -
frontends/riscos/templates/en | 118 -
frontends/riscos/templates/fr | 122 -
frontends/riscos/templates/nl | 120 -
frontends/riscos/textselection.c | 3 +-
frontends/riscos/textselection.h | 2 +-
frontends/riscos/theme_install.c | 63 +-
frontends/riscos/ucstables.h | 2 +-
frontends/riscos/window.c | 357 +-
frontends/riscos/window.h | 11 -
frontends/windows/Makefile | 4 +-
frontends/windows/bitmap.h | 2 +-
frontends/windows/clipboard.c | 131 +
.../pdf/pdf.h => frontends/windows/clipboard.h | 14 +-
frontends/windows/corewindow.c | 25 +-
frontends/windows/drawable.c | 197 +-
frontends/windows/fetch.h | 2 +-
frontends/windows/file.h | 2 +-
frontends/windows/font.h | 4 +-
frontends/windows/gui.c | 63 -
frontends/windows/gui.h | 5 +-
frontends/windows/local_history.c | 1 +
frontends/windows/login.c | 297 -
frontends/windows/login.h | 39 -
frontends/windows/main.c | 28 +-
frontends/windows/res/installer.nsi | 2 +-
frontends/windows/windbg.h | 11 +-
frontends/windows/window.c | 175 +-
frontends/windows/window.h | 6 +-
include/netsurf/{types.h => browser.h} | 29 +-
include/netsurf/browser_window.h | 111 +-
include/netsurf/console.h | 68 +
include/netsurf/content.h | 2 +-
include/netsurf/core_window.h | 31 +-
include/netsurf/misc.h | 34 +-
include/netsurf/ssl_certs.h | 62 +
include/netsurf/window.h | 135 +-
resources/FatMessages | 6347 ++++----
resources/ca-bundle | 481 +-
resources/en/credits.html | 2 +-
resources/en/licence.html | 10 +-
.../icons/local-history.png | Bin 206 -> 206 bytes
resources/icons/show-cookie.png | Bin 0 -> 303 bytes
resources/internal.css | 106 +
resources/it/credits.html | 2 +-
resources/it/licence.html | 2 +-
resources/nl/credits.html | 2 +-
resources/nl/licence.html | 2 +-
test/.gitignore | 1 +
test/Makefile | 15 +-
test/data/Choices-all | 5 +-
test/js/event-onclick-insert.html | 18 +
test/js/inserted-script-async.js | 1 +
test/js/inserted-script-defer.js | 1 +
test/js/inserted-script.html | 39 +
test/js/inserted-script.js | 1 +
test/js/settimeout.html | 17 +
test/js/sleepy-async.html | 13 +
test/monkey-see-monkey-do | 96 +
test/monkey-tests/401login.yaml | 38 +
test/monkey-tests/cache-test.yaml | 35 +
test/monkey-tests/inserted-script.yaml | 28 +
test/monkey-tests/quit-mid-fetch.yaml | 22 +
test/monkey-tests/resource-scheme.yaml | 34 +
test/monkey-tests/simultanious-fetches.yaml | 35 +
test/monkey-tests/sslcert.yaml | 33 +
test/monkey-tests/start-stop-no-js.yaml | 8 +
test/monkey-tests/start-stop.yaml | 6 +
test/monkey_driver.py | 661 +
test/monkeyfarmer.py | 657 +
test/nsoption.c | 8 +-
test/nsurl.c | 26 +-
utils/corestringlist.h | 8 +
utils/dirent.h | 4 +-
utils/errors.h | 3 +
utils/file.h | 2 +-
utils/filename.c | 4 +-
utils/filepath.c | 68 +-
utils/http.h | 1 +
utils/http/Makefile | 2 +-
...strict-transport-security.c => cache-control.c} | 116 +-
utils/http/cache-control.h | 77 +
utils/idna.c | 2 +-
utils/jenkins-build.sh | 39 +-
utils/log.c | 13 +-
utils/log.h | 2 +
utils/messages.c | 65 +
utils/messages.h | 9 +
utils/nsurl.h | 3 +
utils/nsurl/nsurl.c | 65 +-
utils/nsurl/parse.c | 20 +-
utils/nsurl/private.h | 7 +-
utils/time.c | 2 +-
utils/useragent.c | 10 +
utils/useragent.h | 7 +
373 files changed, 36556 insertions(+), 30296 deletions(-)
create mode 100644 content/handlers/image/webp.c
copy content/handlers/{pdf/pdf.h => image/webp.h} (78%)
create mode 100644 content/handlers/javascript/duktape/generics.js
create mode 100644 content/handlers/javascript/duktape/polyfill.js
copy desktop/{browser.c => browser_window.c} (55%)
create mode 100644 desktop/cw_helper.c
copy frontends/riscos/local_history.h => desktop/cw_helper.h (51%)
create mode 100644 docs/UnimplementedJavascript.md
delete mode 100644 docs/UnimplementedJavascript.txt
create mode 100644 docs/jsbinding.md
delete mode 100755 frontends/amiga/login.c
delete mode 100755 frontends/amiga/login.h
delete mode 100644 frontends/atari/login.c
delete mode 100644 frontends/atari/login.h
copy frontends/{gtk => framebuffer}/res/Messages (100%)
copy frontends/{beos => framebuffer}/res/de/welcome.html (100%)
copy frontends/{beos => framebuffer}/res/en/credits.html (100%)
copy frontends/{beos => framebuffer}/res/en/licence.html (100%)
copy frontends/{beos => framebuffer}/res/en/maps.html (100%)
copy frontends/{beos => framebuffer}/res/en/welcome.html (100%)
copy frontends/{beos => framebuffer}/res/it/credits.html (100%)
copy frontends/{beos => framebuffer}/res/it/licence.html (100%)
copy frontends/{beos => framebuffer}/res/ja/welcome.html (100%)
copy frontends/{gtk => framebuffer}/res/nl/credits.html (100%)
copy frontends/{gtk => framebuffer}/res/nl/licence.html (100%)
copy frontends/{gtk => framebuffer}/res/nl/welcome.html (100%)
delete mode 100644 frontends/gtk/login.c
delete mode 100644 frontends/gtk/login.h
delete mode 100644 frontends/gtk/res/login.gtk2.ui
delete mode 100644 frontends/gtk/res/login.gtk3.ui
create mode 100644 frontends/gtk/toolbar_items.h
delete mode 100644 frontends/monkey/farmer.py
copy frontends/{riscos/assert.c => monkey/output.c} (55%)
copy content/handlers/pdf/pdf.h => frontends/monkey/output.h (72%)
delete mode 100644 frontends/riscos/401login.c
create mode 100644 frontends/windows/clipboard.c
copy content/handlers/pdf/pdf.h => frontends/windows/clipboard.h (73%)
delete mode 100644 frontends/windows/login.c
delete mode 100644 frontends/windows/login.h
copy include/netsurf/{types.h => browser.h} (65%)
create mode 100644 include/netsurf/console.h
create mode 100644 include/netsurf/ssl_certs.h
rename frontends/gtk/res/arrow_down_8x32.png => resources/icons/local-history.png (100%)
create mode 100644 resources/icons/show-cookie.png
create mode 100644 test/.gitignore
create mode 100644 test/js/event-onclick-insert.html
create mode 100644 test/js/inserted-script-async.js
create mode 100644 test/js/inserted-script-defer.js
create mode 100644 test/js/inserted-script.html
create mode 100644 test/js/inserted-script.js
create mode 100644 test/js/settimeout.html
create mode 100644 test/js/sleepy-async.html
create mode 100755 test/monkey-see-monkey-do
create mode 100644 test/monkey-tests/401login.yaml
create mode 100644 test/monkey-tests/cache-test.yaml
create mode 100644 test/monkey-tests/inserted-script.yaml
create mode 100644 test/monkey-tests/quit-mid-fetch.yaml
create mode 100644 test/monkey-tests/resource-scheme.yaml
create mode 100644 test/monkey-tests/simultanious-fetches.yaml
create mode 100644 test/monkey-tests/sslcert.yaml
create mode 100644 test/monkey-tests/start-stop-no-js.yaml
create mode 100644 test/monkey-tests/start-stop.yaml
create mode 100755 test/monkey_driver.py
create mode 100644 test/monkeyfarmer.py
copy utils/http/{strict-transport-security.c => cache-control.c} (72%)
create mode 100644 utils/http/cache-control.h
diff --git a/.gitignore b/.gitignore
index fa42a20..4e84e75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,8 +7,7 @@ frontends/riscos/appdir/Resources/fr/Templates,fec
frontends/riscos/appdir/Resources/de/Templates,fec
frontends/riscos/appdir/Resources/nl/Templates,fec
resources/*/Messages
-frontends/gtk/res/*/Messages
-frontends/windows/res/*/Messages
+frontends/*/res/*/Messages
codedocs
nsgtk
nsgtk3
diff --git a/Makefile b/Makefile
index 2cad7d4..8784a46 100644
--- a/Makefile
+++ b/Makefile
@@ -137,6 +137,7 @@ PERL=perl
MKDIR=mkdir
TOUCH=touch
STRIP?=strip
+INSTALL?=install
SPLIT_MESSAGES=$(PERL) utils/split-messages.pl
# build verbosity
@@ -148,7 +149,7 @@ endif
VQ=@
# Override this only if the host compiler is called something different
-HOST_CC := gcc
+BUILD_CC := cc
ifeq ($(TARGET),riscos)
ifeq ($(HOST),riscos)
@@ -319,11 +320,11 @@ else
endif
# compiler versioning to adjust warning flags
-CC_VERSION := $(shell $(CC) -dumpversion)
+CC_VERSION := $(shell $(CC) -dumpfullversion -dumpversion)
CC_MAJOR := $(word 1,$(subst ., ,$(CC_VERSION)))
CC_MINOR := $(word 2,$(subst ., ,$(CC_VERSION)))
define cc_ver_ge
-$(shell expr $(CC_MAJOR) \>= $(1) \& $(CC_MINOR) \>= $(2))
+$(shell expr $(CC_MAJOR) \> $(1) \| \( $(CC_MAJOR) = $(1) \& $(CC_MINOR) \>= $(2) \) )
endef
# CCACHE
@@ -431,6 +432,7 @@ define pkg_config_find_and_add_enabled
endif
NETSURF_FEATURE_$(1)_AVAILABLE := $$(shell $$(PKG_CONFIG) --exists $(2) && echo yes)
+ NETSURF_FEATURE_$(1)_CFLAGS ?= -DWITH_$(1)
ifeq ($$(NETSURF_USE_$(1)),YES)
ifeq ($$(NETSURF_FEATURE_$(1)_AVAILABLE),yes)
@@ -491,6 +493,11 @@ ifeq ($(call cc_ver_ge,4,6),1)
COMMON_WARNFLAGS += -Wno-unused-but-set-variable
endif
+# Implicit fallthrough warnings suppressed by comment
+ifeq ($(call cc_ver_ge,7,1),1)
+ COMMON_WARNFLAGS += -Wimplicit-fallthrough=3
+endif
+
# deal with chaging warning flags for different platforms
ifeq ($(HOST),OpenBSD)
# OpenBSD headers are not compatible with redundant declaration warning
@@ -528,16 +535,10 @@ LDFLAGS += -lz
# Optional libraries with pkgconfig
# define additional CFLAGS and LDFLAGS requirements for pkg-configed libs
-NETSURF_FEATURE_PNG_CFLAGS := -DWITH_PNG
-NETSURF_FEATURE_BMP_CFLAGS := -DWITH_BMP
-NETSURF_FEATURE_GIF_CFLAGS := -DWITH_GIF
-NETSURF_FEATURE_CURL_CFLAGS := -DWITH_CURL
+# We only need to define the ones where the feature name doesn't exactly
+# match the WITH_FEATURE flag
NETSURF_FEATURE_NSSVG_CFLAGS := -DWITH_NS_SVG
-NETSURF_FEATURE_OPENSSL_CFLAGS := -DWITH_OPENSSL
NETSURF_FEATURE_ROSPRITE_CFLAGS := -DWITH_NSSPRITE
-NETSURF_FEATURE_NSPSL_CFLAGS := -DWITH_NSPSL
-NETSURF_FEATURE_NSLOG_CFLAGS := -DWITH_NSLOG
-NETSURF_FEATURE_NSPDF_CFLAGS := -DWITH_NSPDF
# libcurl and openssl ordering matters as if libcurl requires ssl it
# needs to come first in link order to ensure its symbols can be
@@ -552,6 +553,7 @@ else
endif
$(eval $(call pkg_config_find_and_add_enabled,OPENSSL,openssl,OpenSSL))
+$(eval $(call pkg_config_find_and_add_enabled,WEBP,libwebp,WEBP))
$(eval $(call pkg_config_find_and_add_enabled,PNG,libpng,PNG))
$(eval $(call pkg_config_find_and_add_enabled,BMP,libnsbmp,BMP))
$(eval $(call pkg_config_find_and_add_enabled,GIF,libnsgif,GIF))
diff --git a/Makefile.config.example b/Makefile.config.example
index 7fa7f41..988fd0a 100644
--- a/Makefile.config.example
+++ b/Makefile.config.example
@@ -39,3 +39,13 @@
### If you're using the sanitizers and you want it to stop on failure...
# override NETSURF_RECOVER_SANITIZERS := NO
+
+### To change the compiled in log level, alter this.
+# Valid options are: DEEPDEBUG, DEBUG, VERBOSE, INFO, WARNING, ERROR, CRITICAL
+# override NETSURF_LOG_LEVEL := DEBUG
+
+### To change the compiled in default log, change this
+# override NETSURF_BUILTIN_LOG_FILTER := "(level:WARNING || cat:jserrors)"
+
+### To change the compiled in *verbose* log, change this
+# override NETSURF_BUILTIN_VERBOSE_FILTER := "(level:VERBOSE || cat:jserrors)"
diff --git a/Makefile.defaults b/Makefile.defaults
index 85fb9b8..696430d 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -59,6 +59,10 @@ NETSURF_USE_PNG := YES
# Valid options: YES, NO
NETSURF_USE_VIDEO := NO
+# Enable NetSurf's use of libwebp for displaying WEBPs.
+# Valid options: YES, NO, AUTO
+NETSURF_USE_WEBP := AUTO
+
# Enable NetSurf's use of duktape for javascript
# Valid options: YES, NO
NETSURF_USE_DUKTAPE := YES
@@ -78,10 +82,10 @@ NETSURF_USE_NSLOG := AUTO
# Valid options are: DEEPDEBUG, DEBUG, VERBOSE, INFO, WARNING, ERROR, CRITICAL
NETSURF_LOG_LEVEL := INFO
# The log filter set during log initialisation before options are available
-NETSURF_BUILTIN_LOG_FILTER := level:WARNING
+NETSURF_BUILTIN_LOG_FILTER := "(level:WARNING || cat:jserrors)"
# The log filter set during log initialisation before options are available
# if the logging level is set to verbose
-NETSURF_BUILTIN_VERBOSE_FILTER := level:VERBOSE
+NETSURF_BUILTIN_VERBOSE_FILTER := "(level:VERBOSE || cat:jserrors)"
# Enable stripping the NetSurf binary
# Valid options: YES, NO
diff --git a/content/content.c b/content/content.c
index 3cf38b7..5cd3b45 100644
--- a/content/content.c
+++ b/content/content.c
@@ -67,12 +67,12 @@ static void content_convert(struct content *c);
nserror content__init(struct content *c, const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
+ llcache_handle *llcache, const char *fallback_charset,
bool quirks)
{
struct content_user *user_sentinel;
nserror error;
-
+
NSLOG(netsurf, INFO, "url "URL_FMT_SPC" -> %p",
nsurl_access_log(llcache_handle_get_url(llcache)), c);
@@ -96,6 +96,7 @@ nserror content__init(struct content *c, const content_handler *handler,
c->width = 0;
c->height = 0;
c->available_width = 0;
+ c->available_height = 0;
c->quirks = quirks;
c->refresh = 0;
nsu_getmonotonic_ms(&c->time);
@@ -115,7 +116,7 @@ nserror content__init(struct content *c, const content_handler *handler,
content_set_status(c, messages_get("Loading"));
/* Finally, claim low-level cache events */
- error = llcache_handle_change_callback(llcache,
+ error = llcache_handle_change_callback(llcache,
content_llcache_callback, c);
if (error != NSERROR_OK) {
lwc_string_unref(c->mime_type);
@@ -141,13 +142,16 @@ nserror content_llcache_callback(llcache_handle *llcache,
nserror error = NSERROR_OK;
switch (event->type) {
+ case LLCACHE_EVENT_GOT_CERTS:
+ /* Will never happen: handled in hlcache */
+ break;
case LLCACHE_EVENT_HAD_HEADERS:
/* Will never happen: handled in hlcache */
break;
case LLCACHE_EVENT_HAD_DATA:
if (c->handler->process_data != NULL) {
- if (c->handler->process_data(c,
- (const char *) event->data.data.buf,
+ if (c->handler->process_data(c,
+ (const char *) event->data.data.buf,
event->data.data.len) == false) {
llcache_handle_abort(c->llcache);
c->status = CONTENT_STATUS_ERROR;
@@ -172,11 +176,12 @@ nserror content_llcache_callback(llcache_handle *llcache,
case LLCACHE_EVENT_ERROR:
/** \todo Error page? */
c->status = CONTENT_STATUS_ERROR;
- msg_data.error = event->data.msg;
+ msg_data.errordata.errorcode = event->data.error.code;
+ msg_data.errordata.errormsg = event->data.error.msg;
content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
break;
case LLCACHE_EVENT_PROGRESS:
- content_set_status(c, event->data.msg);
+ content_set_status(c, event->data.progress_msg);
msg_data.explicit_status_text = NULL;
content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
break;
@@ -272,7 +277,7 @@ void content_convert(struct content *c)
if (c->locked == true)
return;
-
+
NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p)",
nsurl_access_log(llcache_handle_get_url(c->llcache)), c);
@@ -294,7 +299,7 @@ void content_convert(struct content *c)
void content_set_ready(struct content *c)
{
- /* The content must be locked at this point, as it can only
+ /* The content must be locked at this point, as it can only
* become READY after conversion. */
assert(c->locked);
c->locked = false;
@@ -355,6 +360,7 @@ void content__reformat(struct content *c, bool background,
assert(c->locked == false);
c->available_width = width;
+ c->available_height = height;
if (c->handler->reformat != NULL) {
c->locked = true;
@@ -543,6 +549,27 @@ void content__request_redraw(struct content *c,
content_broadcast(c, CONTENT_MSG_REDRAW, &data);
}
+/* exported interface, documented in content/content.h */
+bool content_exec(struct hlcache_handle *h, const char *src, size_t srclen)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+
+ if (c->locked) {
+ /* Not safe to do stuff */
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, content locked");
+ return false;
+ }
+
+ if (c->handler->exec == NULL) {
+ /* Can't exec something on this content */
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, no exec function");
+ return false;
+ }
+
+ return c->handler->exec(c, src, srclen);
+}
/* exported interface, documented in content/content_protected.h */
bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
@@ -725,7 +752,7 @@ uint32_t content_count_users(struct content *c)
uint32_t counter = 0;
assert(c != NULL);
-
+
for (user = c->user_list; user != NULL; user = user->next)
counter += 1;
@@ -779,19 +806,20 @@ void content_broadcast(struct content *c, content_msg msg,
}
/* exported interface documented in content_protected.h */
-void content_broadcast_errorcode(struct content *c, nserror errorcode)
+void content_broadcast_error(struct content *c, nserror errorcode, const char *msg)
{
struct content_user *user, *next;
union content_msg_data data;
assert(c);
- data.errorcode = errorcode;
+ data.errordata.errorcode = errorcode;
+ data.errordata.errormsg = msg;
for (user = c->user_list->next; user != 0; user = next) {
next = user->next; /* user may be destroyed during callback */
if (user->callback != 0) {
- user->callback(c, CONTENT_MSG_ERRORCODE,
+ user->callback(c, CONTENT_MSG_ERROR,
&data, user->pw);
}
}
@@ -803,22 +831,32 @@ void content_broadcast_errorcode(struct content *c, nserror errorcode)
*
* \param h handle to content that has been opened
* \param bw browser window containing the content
- * \param page content of type CONTENT_HTML containing h, or 0 if not an
+ * \param page content of type CONTENT_HTML containing h, or NULL if not an
* object within a page
- * \param params object parameters, or 0 if not an object
+ * \param params object parameters, or NULL if not an object
*
* Calls the open function for the content.
*/
-void content_open(hlcache_handle *h, struct browser_window *bw,
- struct content *page, struct object_params *params)
+nserror
+content_open(hlcache_handle *h,
+ struct browser_window *bw,
+ struct content *page,
+ struct object_params *params)
{
- struct content *c = hlcache_handle_get_content(h);
+ struct content *c;
+ nserror res;
+
+ c = hlcache_handle_get_content(h);
assert(c != 0);
NSLOG(netsurf, INFO, "content %p %s", c,
nsurl_access_log(llcache_handle_get_url(c->llcache)));
- if (c->handler->open != NULL)
- c->handler->open(c, bw, page, params);
+ if (c->handler->open != NULL) {
+ res = c->handler->open(c, bw, page, params);
+ } else {
+ res = NSERROR_OK;
+ }
+ return res;
}
@@ -828,14 +866,30 @@ void content_open(hlcache_handle *h, struct browser_window *bw,
* Calls the close function for the content.
*/
-void content_close(hlcache_handle *h)
+nserror content_close(hlcache_handle *h)
{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
+ struct content *c;
+ nserror res;
+
+ c = hlcache_handle_get_content(h);
+ if (c == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ if ((c->status != CONTENT_STATUS_READY) &&
+ (c->status != CONTENT_STATUS_DONE)) {
+ /* status is not read or done so nothing to do */
+ return NSERROR_INVALID;
+ }
+
NSLOG(netsurf, INFO, "content %p %s", c,
nsurl_access_log(llcache_handle_get_url(c->llcache)));
- if (c->handler->close != NULL)
- c->handler->close(c);
+ if (c->handler->close != NULL) {
+ res = c->handler->close(c);
+ } else {
+ res = NSERROR_OK;
+ }
+ return res;
}
@@ -989,7 +1043,7 @@ content_find_rfc5988_link(hlcache_handle *h, lwc_string *rel)
}
struct content_rfc5988_link *
-content__free_rfc5988_link(struct content_rfc5988_link *link)
+content__free_rfc5988_link(struct content_rfc5988_link *link)
{
struct content_rfc5988_link *next;
@@ -1014,10 +1068,10 @@ content__free_rfc5988_link(struct content_rfc5988_link *link)
return next;
}
-bool content__add_rfc5988_link(struct content *c,
+bool content__add_rfc5988_link(struct content *c,
const struct content_rfc5988_link *link)
{
- struct content_rfc5988_link *newlink;
+ struct content_rfc5988_link *newlink;
union content_msg_data msg_data;
/* a link relation must be present for it to be a link */
@@ -1032,7 +1086,7 @@ bool content__add_rfc5988_link(struct content *c,
newlink = calloc(1, sizeof(struct content_rfc5988_link));
if (newlink == NULL) {
- return false;
+ return false;
}
/* copy values */
@@ -1216,27 +1270,21 @@ int content__get_available_width(struct content *c)
/* exported interface documented in content/content.h */
-const char *content_get_source_data(hlcache_handle *h, unsigned long *size)
+const uint8_t *content_get_source_data(hlcache_handle *h, size_t *size)
{
return content__get_source_data(hlcache_handle_get_content(h), size);
}
/* exported interface documented in content/content_protected.h */
-const char *content__get_source_data(struct content *c, unsigned long *size)
+const uint8_t *content__get_source_data(struct content *c, size_t *size)
{
- const uint8_t *data;
- size_t len;
-
assert(size != NULL);
+ /** \todo check if the content check should be an assert */
if (c == NULL)
return NULL;
- data = llcache_handle_get_source_data(c->llcache, &len);
-
- *size = (unsigned long) len;
-
- return (const char *) data;
+ return llcache_handle_get_source_data(c->llcache, size);
}
/* exported interface documented in content/content.h */
@@ -1283,9 +1331,9 @@ struct bitmap *content__get_bitmap(struct content *c)
{
struct bitmap *bitmap = NULL;
- if ((c != NULL) &&
- (c->handler != NULL) &&
- (c->handler->type != NULL) &&
+ if ((c != NULL) &&
+ (c->handler != NULL) &&
+ (c->handler->type != NULL) &&
(c->handler->type() == CONTENT_IMAGE) &&
(c->handler->get_internal != NULL) ) {
bitmap = c->handler->get_internal(c, NULL);
@@ -1307,14 +1355,14 @@ bool content__get_opaque(struct content *c)
{
bool opaque = false;
- if ((c != NULL) &&
- (c->handler != NULL) &&
- (c->handler->type != NULL) &&
+ if ((c != NULL) &&
+ (c->handler != NULL) &&
+ (c->handler->type != NULL) &&
(c->handler->type() == CONTENT_IMAGE) &&
(c->handler->get_internal != NULL) ) {
struct bitmap *bitmap = NULL;
bitmap = c->handler->get_internal(c, NULL);
- if (bitmap != NULL) {
+ if (bitmap != NULL) {
opaque = guit->bitmap->get_opaque(bitmap);
}
}
@@ -1469,7 +1517,7 @@ nserror content__clone(const struct content *c, struct content *nc)
nc->locked = c->locked;
nc->total_size = c->total_size;
nc->http_code = c->http_code;
-
+
return NSERROR_OK;
}
@@ -1482,11 +1530,10 @@ nserror content__clone(const struct content *c, struct content *nc)
nserror content_abort(struct content *c)
{
NSLOG(netsurf, INFO, "Aborting %p", c);
-
+
if (c->handler->stop != NULL)
c->handler->stop(c);
-
+
/* And for now, abort our llcache object */
return llcache_handle_abort(c->llcache);
}
-
diff --git a/content/content.h b/content/content.h
index e555df2..a5bf46c 100644
--- a/content/content.h
+++ b/content/content.h
@@ -33,6 +33,7 @@
#include "content/content_factory.h"
#include "desktop/search.h" /* search flags enum */
#include "netsurf/mouse.h" /* mouse state enums */
+#include "netsurf/console.h" /* console state and flags enums */
struct browser_window;
struct browser_window_features;
@@ -42,6 +43,8 @@ struct hlcache_handle;
struct object_params;
struct rect;
struct redraw_context;
+struct llcache_query_msg;
+struct ssl_cert_info;
/** Status of a content */
typedef enum {
@@ -56,11 +59,12 @@ typedef enum {
/** Used in callbacks to indicate what has occurred. */
typedef enum {
+ CONTENT_MSG_LOG, /**< Content wishes to log something */
+ CONTENT_MSG_SSL_CERTS, /**< Content is from SSL and this is its chain */
CONTENT_MSG_LOADING, /**< fetching or converting */
CONTENT_MSG_READY, /**< may be displayed */
CONTENT_MSG_DONE, /**< finished */
CONTENT_MSG_ERROR, /**< error occurred */
- CONTENT_MSG_ERRORCODE, /**< error occurred return nserror */
CONTENT_MSG_REDIRECT, /**< fetch url redirect occured */
CONTENT_MSG_STATUS, /**< new status string */
CONTENT_MSG_REFORMAT, /**< content_reformat done */
@@ -69,6 +73,7 @@ typedef enum {
CONTENT_MSG_DOWNLOAD, /**< download, not for display */
CONTENT_MSG_LINK, /**< RFC5988 link */
CONTENT_MSG_GETCTX, /**< Javascript context */
+ CONTENT_MSG_GETDIMS, /**< Get viewport dimensions. */
CONTENT_MSG_SCROLL, /**< Request to scroll content */
CONTENT_MSG_DRAGSAVE, /**< Allow drag saving of content */
CONTENT_MSG_SAVELINK, /**< Allow URL to be saved */
@@ -95,10 +100,29 @@ struct content_rfc5988_link {
/** Extra data for some content_msg messages. */
union content_msg_data {
- /** CONTENT_MSG_ERROR - Error message */
- const char *error;
- /** CONTENT_MSG_ERRORCODE - Error code */
- nserror errorcode;
+ /** CONTENT_MSG_LOG - Information for logging */
+ struct {
+ browser_window_console_source src; /**< The source of the logging */
+ const char *msg; /**< The message to log */
+ size_t msglen; /**< The length of that message */
+ browser_window_console_flags flags; /**< The flags of the logging */
+ } log;
+ /** CONTENT_MSG_SSL_CERTS - The certificate chain from the underlying fetch */
+ struct {
+ const struct ssl_cert_info *certs; /**< The chain */
+ size_t num; /**< The number of certs in the chain */
+ } certs;
+ /** CONTENT_MSG_ERROR - Error from content or underlying fetch */
+ struct {
+ nserror errorcode; /**< The error code to convey meaning */
+ const char *errormsg; /**< The message.
+ * if NSERROR_UNKNOWN then this is the
+ * direct message, otherwise is some
+ * kind of metadata (e.g. a message name
+ * or somesuch) but always a nul
+ * terminated string.
+ */
+ } errordata;
/** CONTENT_MSG_REDIRECT - Redirect info */
struct {
struct nsurl *from; /**< Redirect origin */
@@ -131,6 +155,12 @@ union content_msg_data {
struct content_rfc5988_link *rfc5988_link;
/** CONTENT_MSG_GETCTX - Javascript context */
struct jscontext **jscontext;
+ /** CONTENT_MSG_GETDIMS - Get the viewport dimensions */
+ struct {
+ /* TODO: Consider getting screen_width, screen_height too. */
+ unsigned *viewport_width;
+ unsigned *viewport_height;
+ } getdims;
/** CONTENT_MSG_SCROLL - Part of content to scroll to show */
struct {
/** if true, scroll to show area given by (x0, y0) and (x1,y1).
@@ -262,10 +292,10 @@ void content_mouse_action(struct hlcache_handle *h, struct browser_window *bw,
bool content_keypress(struct hlcache_handle *h, uint32_t key);
-void content_open(struct hlcache_handle *h, struct browser_window *bw,
+nserror content_open(struct hlcache_handle *h, struct browser_window *bw,
struct content *page, struct object_params *params);
-void content_close(struct hlcache_handle *h);
+nserror content_close(struct hlcache_handle *h);
void content_clear_selection(struct hlcache_handle *h);
@@ -387,6 +417,17 @@ bool content_get_quirks(struct hlcache_handle *h);
bool content_is_locked(struct hlcache_handle *h);
+/**
+ * Execute some JavaScript code inside a content object.
+ *
+ * Runs the passed in JavaScript code in the content object's context.
+ *
+ * \param h The handle to the content
+ * \param src The JavaScript source code
+ * \param srclen The length of the source code
+ * \return Whether the JS function was successfully injected into the content
+ */
+bool content_exec(struct hlcache_handle *h, const char *src, size_t srclen);
#endif
diff --git a/content/content_factory.c b/content/content_factory.c
index 935354a..44fc333 100644
--- a/content/content_factory.c
+++ b/content/content_factory.c
@@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Content factory (implementation)
+/**
+ * \file
+ * Content factory implementation
*/
#include <assert.h>
diff --git a/content/content_protected.h b/content/content_protected.h
index 941b5a7..fb3639c 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -19,7 +19,7 @@
/**
* \file
- * Content handling interface.
+ * Protected interface to Content handling.
*
* The content functions manipulate struct contents, which correspond to URLs.
*/
@@ -77,9 +77,9 @@ struct content_handler {
bool (*redraw)(struct content *c, struct content_redraw_data *data,
const struct rect *clip,
const struct redraw_context *ctx);
- void (*open)(struct content *c, struct browser_window *bw,
+ nserror (*open)(struct content *c, struct browser_window *bw,
struct content *page, struct object_params *params);
- void (*close)(struct content *c);
+ nserror (*close)(struct content *c);
void (*clear_selection)(struct content *c);
char * (*get_selection)(struct content *c);
nserror (*get_contextual_content)(struct content *c, int x, int y,
@@ -99,6 +99,7 @@ struct content_handler {
content_type (*type)(void);
void (*add_user)(struct content *c);
void (*remove_user)(struct content *c);
+ bool (*exec)(struct content *c, const char *src, size_t srclen);
/**
* handler dependant content sensitive internal data interface.
@@ -135,7 +136,8 @@ struct content {
content_status status; /**< Current status. */
int width, height; /**< Dimensions, if applicable. */
- int available_width; /**< Available width (eg window width). */
+ int available_width; /**< Viewport width. */
+ int available_height; /**< Viewport height. */
bool quirks; /**< Content is in quirks mode */
char *fallback_charset; /**< Fallback charset, or NULL */
@@ -193,9 +195,13 @@ void content_set_status(struct content *c, const char *status_message);
void content_broadcast(struct content *c, content_msg msg,
const union content_msg_data *data);
/**
- * Send an errorcode message to all users.
+ * Send an error message to all users.
+ *
+ * \param c The content whose users should be informed of an error
+ * \param errorcode The nserror code to send
+ * \param msg The error message to send alongside
*/
-void content_broadcast_errorcode(struct content *c, nserror errorcode);
+void content_broadcast_error(struct content *c, nserror errorcode, const char *msg);
void content_add_error(struct content *c, const char *token,
unsigned int line);
@@ -275,7 +281,7 @@ int content__get_available_width(struct content *c);
* \param size Pointer to location to receive byte size of source.
* \return Pointer to source data.
*/
-const char *content__get_source_data(struct content *c, unsigned long *size);
+const uint8_t *content__get_source_data(struct content *c, size_t *size);
/**
* Invalidate content reuse data.
diff --git a/content/fetch.c b/content/fetch.c
index 7665029..2ac86a8 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -712,6 +712,23 @@ fetch_multipart_data_clone(const struct fetch_multipart_data *list)
return result;
}
+
+/* exported interface documented in content/fetch.h */
+const char *
+fetch_multipart_data_find(const struct fetch_multipart_data *list,
+ const char *name)
+{
+ while (list != NULL) {
+ if (strcmp(list->name, name) == 0) {
+ return list->value;
+ }
+ list = list->next;
+ }
+
+ return NULL;
+}
+
+
/* exported interface documented in content/fetch.h */
void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
{
@@ -730,6 +747,43 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
}
}
+
+/* exported interface documented in content/fetch.h */
+nserror
+fetch_multipart_data_new_kv(struct fetch_multipart_data **list,
+ const char *name,
+ const char *value)
+{
+ struct fetch_multipart_data *newdata;
+
+ assert(list);
+
+ newdata = calloc(sizeof(*newdata), 1);
+
+ if (newdata == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ newdata->name = strdup(name);
+ if (newdata->name == NULL) {
+ free(newdata);
+ return NSERROR_NOMEM;
+ }
+
+ newdata->value = strdup(value);
+ if (newdata->value == NULL) {
+ free(newdata->name);
+ free(newdata);
+ return NSERROR_NOMEM;
+ }
+
+ newdata->next = *list;
+ *list = newdata;
+
+ return NSERROR_OK;
+}
+
+
/* exported interface documented in content/fetch.h */
void
fetch_send_callback(const fetch_msg *msg, struct fetch *fetch)
diff --git a/content/fetch.h b/content/fetch.h
index 5521778..66be857 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -28,6 +28,7 @@
#include "utils/config.h"
#include "utils/nsurl.h"
#include "utils/inet.h"
+#include "netsurf/ssl_certs.h"
struct content;
struct fetch;
@@ -42,6 +43,7 @@ typedef enum {
FETCH_ERROR,
FETCH_REDIRECT,
FETCH_NOTMODIFIED,
+ FETCH_CERTS,
FETCH_AUTH,
FETCH_CERT_ERR,
FETCH_SSL_ERR
@@ -70,29 +72,21 @@ typedef struct fetch_msg {
struct {
const struct ssl_cert_info *certs;
size_t num_certs;
- } cert_err;
+ } certs;
} data;
} fetch_msg;
-/** Fetch POST multipart data */
+/**
+ * Fetch POST multipart data
+ */
struct fetch_multipart_data {
- bool file; /**< Item is a file */
- char *name; /**< Name of item */
- char *value; /**< Item value */
- char *rawfile; /**< Raw filename if file is true */
+ struct fetch_multipart_data *next; /**< Next in linked list */
- struct fetch_multipart_data *next; /**< Next in linked list */
-};
+ char *name; /**< Name of item */
+ char *value; /**< Item value */
-struct ssl_cert_info {
- long version; /**< Certificate version */
- char not_before[32]; /**< Valid from date */
- char not_after[32]; /**< Valid to date */
- int sig_type; /**< Signature type */
- long serial; /**< Serial number */
- char issuer[256]; /**< Issuer details */
- char subject[256]; /**< Subject details */
- int cert_type; /**< Certificate type */
+ char *rawfile; /**< Raw filename if file is true */
+ bool file; /**< Item is a file */
};
typedef void (*fetch_callback)(const fetch_msg *msg, void *p);
@@ -175,6 +169,30 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list);
struct fetch_multipart_data *fetch_multipart_data_clone(const struct fetch_multipart_data *list);
/**
+ * Find an entry in a fetch_multipart_data
+ *
+ * \param list Pointer to the multipart list
+ * \param name The name to look for in the list
+ * \return The value found, or NULL if not present
+ */
+const char *fetch_multipart_data_find(const struct fetch_multipart_data *list,
+ const char *name);
+
+/**
+ * Create an entry for a fetch_multipart_data
+ *
+ * If an entry exists of the same name, it will *NOT* be overwritten
+ *
+ * \param list Pointer to the pointer to the current multipart list
+ * \param name The name of the entry to create
+ * \param value The value of the entry to create
+ * \return The result of the attempt
+ */
+nserror fetch_multipart_data_new_kv(struct fetch_multipart_data **list,
+ const char *name,
+ const char *value);
+
+/**
* send message to fetch
*/
void fetch_send_callback(const fetch_msg *msg, struct fetch *fetch);
diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index 4d14020..df51410 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -31,10 +31,12 @@
#include <stdio.h>
#include <stdarg.h>
+#include "utils/log.h"
#include "testament.h"
#include "utils/corestrings.h"
#include "utils/nsoption.h"
#include "utils/utils.h"
+#include "utils/messages.h"
#include "utils/ring.h"
#include "content/fetch.h"
@@ -42,12 +44,13 @@
#include "content/fetchers/about.h"
#include "image/image_cache.h"
-
struct fetch_about_context;
typedef bool (*fetch_about_handler)(struct fetch_about_context *);
-/** Context for an about fetch */
+/**
+ * Context for an about fetch
+ */
struct fetch_about_context {
struct fetch_about_context *r_next, *r_prev;
@@ -58,14 +61,39 @@ struct fetch_about_context {
nsurl *url; /**< The full url the fetch refers to */
+ const struct fetch_multipart_data *multipart; /**< post data */
+
fetch_about_handler handler;
};
static struct fetch_about_context *ring = NULL;
-/** issue fetch callbacks with locking */
-static inline bool fetch_about_send_callback(const fetch_msg *msg,
- struct fetch_about_context *ctx)
+/**
+ * handler info for about scheme
+ */
+struct about_handlers {
+ const char *name; /**< name to match in url */
+ int name_len;
+ lwc_string *lname; /**< Interned name */
+ fetch_about_handler handler; /**< handler for the url */
+ bool hidden; /**< If entry should be hidden in listing */
+};
+
+/**
+ * authentication query description if messages fails to retrieve usable text
+ */
+static const char *authentication_description_fallback = "The site %s is requesting your username and password. The realm is \"%s\"";
+
+/**
+ * privacy query description if messages fails to retrieve usable text
+ */
+static const char *privacy_description_fallback = "A privacy error occurred while communicating with %s this may be a site configuration error or an attempt to steal private information (passwords, messages or credit cards)";
+
+/**
+ * issue fetch callbacks with locking
+ */
+static inline bool
+fetch_about_send_callback(const fetch_msg *msg, struct fetch_about_context *ctx)
{
ctx->locked = true;
fetch_send_callback(msg, ctx->fetchh);
@@ -74,8 +102,16 @@ static inline bool fetch_about_send_callback(const fetch_msg *msg,
return ctx->aborted;
}
-static bool fetch_about_send_header(struct fetch_about_context *ctx,
- const char *fmt, ...)
+static inline bool
+fetch_about_send_finished(struct fetch_about_context *ctx)
+{
+ fetch_msg msg;
+ msg.type = FETCH_FINISHED;
+ return fetch_about_send_callback(&msg, ctx);
+}
+
+static bool
+fetch_about_send_header(struct fetch_about_context *ctx, const char *fmt, ...)
{
char header[64];
fetch_msg msg;
@@ -91,14 +127,74 @@ static bool fetch_about_send_header(struct fetch_about_context *ctx,
msg.data.header_or_data.buf = (const uint8_t *) header;
msg.data.header_or_data.len = strlen(header);
- fetch_about_send_callback(&msg, ctx);
+ return fetch_about_send_callback(&msg, ctx);
+}
- return ctx->aborted;
+/**
+ * send formatted data on a fetch
+ */
+static nserror ssenddataf(struct fetch_about_context *ctx, const char *fmt, ...)
+{
+ char buffer[1024];
+ fetch_msg msg;
+ va_list ap;
+ int slen;
+
+ va_start(ap, fmt);
+
+ slen = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+
+ va_end(ap);
+
+ if (slen >= (int)sizeof(buffer)) {
+ return NSERROR_NOSPACE;
+ }
+
+ msg.type = FETCH_DATA;
+ msg.data.header_or_data.buf = (const uint8_t *) buffer;
+ msg.data.header_or_data.len = slen;
+
+ if (fetch_about_send_callback(&msg, ctx)) {
+ return NSERROR_INVALID;
+ }
+
+ return NSERROR_OK;
}
+/**
+ * Generate a 500 server error respnse
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
+static bool fetch_about_srverror(struct fetch_about_context *ctx)
+{
+ nserror res;
+
+ fetch_set_http_code(ctx->fetchh, 500);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
+ return false;
+
+ res = ssenddataf(ctx, "Server error 500");
+ if (res != NSERROR_OK) {
+ return false;
+ }
+
+ fetch_about_send_finished(ctx);
+
+ return true;
+}
+/**
+ * Handler to generate about scheme cache page.
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_blank_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -129,6 +225,12 @@ fetch_about_blank_handler_aborted:
}
+/**
+ * Handler to generate about scheme credits page.
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_credits_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -145,6 +247,12 @@ static bool fetch_about_credits_handler(struct fetch_about_context *ctx)
}
+/**
+ * Handler to generate about scheme licence page.
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_licence_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -160,6 +268,7 @@ static bool fetch_about_licence_handler(struct fetch_about_context *ctx)
return true;
}
+
/**
* Handler to generate about:cache page.
*
@@ -175,7 +284,8 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
int code = 200;
int slen;
unsigned int cent_loop = 0;
- int res = 0;
+ int elen = 0; /* entry length */
+ nserror res;
/* content is going to return ok */
fetch_set_http_code(ctx->fetchh, code);
@@ -184,12 +294,9 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
goto fetch_about_imagecache_handler_aborted;
- msg.type = FETCH_DATA;
- msg.data.header_or_data.buf = (const uint8_t *) buffer;
-
/* page head */
- slen = snprintf(buffer, sizeof buffer,
- "<html>\n<head>\n"
+ res = ssenddataf(ctx,
+ "<html>\n<head>\n"
"<title>NetSurf Browser Image Cache Status</title>\n"
"<link rel=\"stylesheet\" type=\"text/css\" "
"href=\"resource:internal.css\">\n"
@@ -199,10 +306,10 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
"<a href=\"http://www.netsurf-browser.org/\">"
"<img src=\"resource:netsurf.png\" alt=\"NetSurf\"></a>"
"</p>\n"
- "<h1>NetSurf Browser Image Cache Status</h1>\n" );
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ "<h1>NetSurf Browser Image Cache Status</h1>\n");
+ if (res != NSERROR_OK) {
goto fetch_about_imagecache_handler_aborted;
+ }
/* image cache summary */
slen = image_cache_snsummaryf(buffer, sizeof(buffer),
@@ -222,17 +329,20 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
"</p>\n"
"<p>Bitmap of size %w had most (%x) conversions</p>\n"
"<h2>Current image cache contents</h2>\n");
- if (slen >= (int) (sizeof(buffer)))
+ if (slen >= (int) (sizeof(buffer))) {
goto fetch_about_imagecache_handler_aborted; /* overflow */
+ }
+ /* send image cache summary */
+ msg.type = FETCH_DATA;
+ msg.data.header_or_data.buf = (const uint8_t *) buffer;
msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ if (fetch_about_send_callback(&msg, ctx)) {
goto fetch_about_imagecache_handler_aborted;
-
+ }
/* image cache entry table */
- slen = snprintf(buffer, sizeof buffer,
- "<p class=\"imagecachelist\">\n"
+ res = ssenddataf(ctx, "<p class=\"imagecachelist\">\n"
"<strong>"
"<span>Entry</span>"
"<span>Content Key</span>"
@@ -243,8 +353,14 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
"<span>Bitmap Size</span>"
"<span>Source</span>"
"</strong>\n");
+ if (res != NSERROR_OK) {
+ goto fetch_about_imagecache_handler_aborted;
+ }
+
+ slen = 0;
do {
- res = image_cache_snentryf(buffer + slen, sizeof buffer - slen,
+ elen = image_cache_snentryf(buffer + slen,
+ sizeof buffer - slen,
cent_loop,
"<a href=\"%U\">"
"<span>%e</span>"
@@ -256,10 +372,10 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
"<span>%s</span>"
"<span>%o</span>"
"</a>\n");
- if (res <= 0)
+ if (elen <= 0)
break; /* last option */
- if (res >= (int) (sizeof buffer - slen)) {
+ if (elen >= (int) (sizeof buffer - slen)) {
/* last entry would not fit in buffer, submit buffer */
msg.data.header_or_data.len = slen;
if (fetch_about_send_callback(&msg, ctx))
@@ -267,10 +383,10 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
slen = 0;
} else {
/* normal addition */
- slen += res;
+ slen += elen;
cent_loop++;
}
- } while (res > 0);
+ } while (elen > 0);
slen += snprintf(buffer + slen, sizeof buffer - slen,
"</p>\n</body>\n</html>\n");
@@ -279,8 +395,7 @@ static bool fetch_about_imagecache_handler(struct fetch_about_context *ctx)
if (fetch_about_send_callback(&msg, ctx))
goto fetch_about_imagecache_handler_aborted;
- msg.type = FETCH_FINISHED;
- fetch_about_send_callback(&msg, ctx);
+ fetch_about_send_finished(ctx);
return true;
@@ -288,50 +403,64 @@ fetch_about_imagecache_handler_aborted:
return false;
}
-/** Handler to generate about:config page */
+
+/**
+ * Handler to generate about scheme config page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_config_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
char buffer[1024];
- int code = 200;
- int slen;
+ int slen = 0;
unsigned int opt_loop = 0;
- int res = 0;
+ int elen = 0; /* entry length */
+ nserror res;
/* content is going to return ok */
- fetch_set_http_code(ctx->fetchh, code);
+ fetch_set_http_code(ctx->fetchh, 200);
/* content type */
- if (fetch_about_send_header(ctx, "Content-Type: text/html"))
+ if (fetch_about_send_header(ctx, "Content-Type: text/html")) {
goto fetch_about_config_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<html>\n<head>\n"
+ "<title>NetSurf Browser Config</title>\n"
+ "<link rel=\"stylesheet\" type=\"text/css\" "
+ "href=\"resource:internal.css\">\n"
+ "</head>\n"
+ "<body id =\"configlist\">\n"
+ "<p class=\"banner\">"
+ "<a href=\"http://www.netsurf-browser.org/\">"
+ "<img src=\"resource:netsurf.png\""
+ " alt=\"NetSurf\"></a>"
+ "</p>\n"
+ "<h1>NetSurf Browser Config</h1>\n"
+ "<table class=\"config\">\n"
+ "<tr><th>Option</th>"
+ "<th>Type</th>"
+ "<th>Provenance</th>"
+ "<th>Setting</th></tr>\n");
+ if (res != NSERROR_OK) {
+ goto fetch_about_config_handler_aborted;
+ }
msg.type = FETCH_DATA;
msg.data.header_or_data.buf = (const uint8_t *) buffer;
- slen = snprintf(buffer, sizeof buffer,
- "<html>\n<head>\n"
- "<title>NetSurf Browser Config</title>\n"
- "<link rel=\"stylesheet\" type=\"text/css\" "
- "href=\"resource:internal.css\">\n"
- "</head>\n"
- "<body id =\"configlist\">\n"
- "<p class=\"banner\">"
- "<a href=\"http://www.netsurf-browser.org/\">"
- "<img src=\"resource:netsurf.png\" alt=\"NetSurf\"></a>"
- "</p>\n"
- "<h1>NetSurf Browser Config</h1>\n"
- "<table class=\"config\">\n"
- "<tr><th>Option</th><th>Type</th><th>Provenance</th><th>Setting</th></tr>\n");
-
do {
- res = nsoption_snoptionf(buffer + slen,
+ elen = nsoption_snoptionf(buffer + slen,
sizeof buffer - slen,
opt_loop,
"<tr><th>%k</th><td>%t</td><td>%p</td><td>%V</td></tr>\n");
- if (res <= 0)
+ if (elen <= 0)
break; /* last option */
- if (res >= (int) (sizeof buffer - slen)) {
+ if (elen >= (int) (sizeof buffer - slen)) {
/* last entry would not fit in buffer, submit buffer */
msg.data.header_or_data.len = slen;
if (fetch_about_send_callback(&msg, ctx))
@@ -339,10 +468,10 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx)
slen = 0;
} else {
/* normal addition */
- slen += res;
+ slen += elen;
opt_loop++;
}
- } while (res > 0);
+ } while (elen > 0);
slen += snprintf(buffer + slen, sizeof buffer - slen,
"</table>\n</body>\n</html>\n");
@@ -351,8 +480,7 @@ static bool fetch_about_config_handler(struct fetch_about_context *ctx)
if (fetch_about_send_callback(&msg, ctx))
goto fetch_about_config_handler_aborted;
- msg.type = FETCH_FINISHED;
- fetch_about_send_callback(&msg, ctx);
+ fetch_about_send_finished(ctx);
return true;
@@ -361,8 +489,12 @@ fetch_about_config_handler_aborted:
}
-/** Generate the text of a Choices file which represents the current
+/**
+ * Generate the text of a Choices file which represents the current
* in use options.
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
*/
static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
{
@@ -411,8 +543,7 @@ static bool fetch_about_choices_handler(struct fetch_about_context *ctx)
if (fetch_about_send_callback(&msg, ctx))
goto fetch_about_choices_handler_aborted;
- msg.type = FETCH_FINISHED;
- fetch_about_send_callback(&msg, ctx);
+ fetch_about_send_finished(ctx);
return true;
@@ -420,38 +551,39 @@ fetch_about_choices_handler_aborted:
return false;
}
-/** Generate the text of an svn testament which represents the current
+
+typedef struct {
+ const char *leaf;
+ const char *modtype;
+} modification_t;
+
+/**
+ * Generate the text of an svn testament which represents the current
* build-tree status
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
*/
-typedef struct { const char *leaf; const char *modtype; } modification_t;
static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
{
+ nserror res;
static modification_t modifications[] = WT_MODIFICATIONS;
- fetch_msg msg;
- char buffer[1024];
- int code = 200;
- int slen;
- int i;
-
+ int modidx; /* midification index */
/* content is going to return ok */
- fetch_set_http_code(ctx->fetchh, code);
+ fetch_set_http_code(ctx->fetchh, 200);
/* content type */
if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
goto fetch_about_testament_handler_aborted;
- msg.type = FETCH_DATA;
- msg.data.header_or_data.buf = (const uint8_t *) buffer;
-
- slen = snprintf(buffer, sizeof buffer,
- "# Automatically generated by NetSurf build system\n\n");
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ res = ssenddataf(ctx,
+ "# Automatically generated by NetSurf build system\n\n");
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
+ }
- slen = snprintf(buffer, sizeof buffer,
+ res = ssenddataf(ctx,
#if defined(WT_BRANCHISTRUNK) || defined(WT_BRANCHISMASTER)
"# This is a *DEVELOPMENT* build from the main line.\n\n"
#elif defined(WT_BRANCHISTAG) && (WT_MODIFIED == 0)
@@ -472,54 +604,44 @@ static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
"# This build carries the CI build number '" CI_BUILD "'\n\n"
#endif
);
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
+ }
-
- slen = snprintf(buffer, sizeof buffer,
- "Built by %s (%s) from %s at revision %s on %s\n\n",
- GECOS, USERNAME, WT_BRANCHPATH, WT_REVID, WT_COMPILEDATE);
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ res = ssenddataf(ctx,
+ "Built by %s (%s) from %s at revision %s on %s\n\n",
+ GECOS, USERNAME, WT_BRANCHPATH, WT_REVID, WT_COMPILEDATE);
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
+ }
- slen = snprintf(buffer, sizeof buffer,
- "Built on %s in %s\n\n",
- WT_HOSTNAME, WT_ROOT);
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ res = ssenddataf(ctx, "Built on %s in %s\n\n", WT_HOSTNAME, WT_ROOT);
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
+ }
if (WT_MODIFIED > 0) {
- slen = snprintf(buffer, sizeof buffer,
+ res = ssenddataf(ctx,
"Working tree has %d modification%s\n\n",
WT_MODIFIED, WT_MODIFIED == 1 ? "" : "s");
} else {
- slen = snprintf(buffer, sizeof buffer,
- "Working tree is not modified.\n");
+ res = ssenddataf(ctx, "Working tree is not modified.\n");
}
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
+ }
- for (i = 0; i < WT_MODIFIED; ++i) {
- slen = snprintf(buffer, sizeof buffer,
- " %s %s\n",
- modifications[i].modtype,
- modifications[i].leaf);
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ for (modidx = 0; modidx < WT_MODIFIED; ++modidx) {
+ res = ssenddataf(ctx,
+ " %s %s\n",
+ modifications[modidx].modtype,
+ modifications[modidx].leaf);
+ if (res != NSERROR_OK) {
goto fetch_about_testament_handler_aborted;
-
+ }
}
- msg.type = FETCH_FINISHED;
- fetch_about_send_callback(&msg, ctx);
+ fetch_about_send_finished(ctx);
return true;
@@ -527,6 +649,13 @@ fetch_about_testament_handler_aborted:
return false;
}
+
+/**
+ * Handler to generate about scheme logo page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_logo_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -542,6 +671,13 @@ static bool fetch_about_logo_handler(struct fetch_about_context *ctx)
return true;
}
+
+/**
+ * Handler to generate about scheme welcome page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_welcome_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -557,6 +693,13 @@ static bool fetch_about_welcome_handler(struct fetch_about_context *ctx)
return true;
}
+
+/**
+ * Handler to generate about scheme maps page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
static bool fetch_about_maps_handler(struct fetch_about_context *ctx)
{
fetch_msg msg;
@@ -572,49 +715,507 @@ static bool fetch_about_maps_handler(struct fetch_about_context *ctx)
return true;
}
+
+/**
+ * generate the description of the login query
+ */
+static nserror
+get_authentication_description(struct nsurl *url,
+ const char *realm,
+ const char *username,
+ const char *password,
+ char **out_str)
+{
+ nserror res;
+ char *url_s;
+ size_t url_l;
+ char *str = NULL;
+ int slen;
+ const char *key;
+
+ res = nsurl_get(url, NSURL_HOST, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ if ((*username == 0) && (*password == 0)) {
+ key = "LoginDescription";
+ } else {
+ key = "LoginAgain";
+ }
+
+ str = messages_get_buff(key, url_s, realm);
+ NSLOG(netsurf, INFO,
+ "key:%s url:%s realm:%s str:%s", key, url_s, realm, str);
+
+ if ((str != NULL) && (strcmp(key, str) != 0)) {
+ *out_str = str;
+ } else {
+ /* no message so fallback */
+ slen = snprintf(str, 0, authentication_description_fallback,
+ url_s, realm) + 1;
+ str = malloc(slen);
+ if (str == NULL) {
+ res = NSERROR_NOMEM;
+ } else {
+ snprintf(str, slen, authentication_description_fallback,
+ url_s, realm);
+ *out_str = str;
+ }
+ }
+
+ free(url_s);
+
+ return res;
+}
+
+
+/**
+ * Handler to generate about scheme authentication query page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
+static bool fetch_about_query_auth_handler(struct fetch_about_context *ctx)
+{
+ nserror res;
+ char *url_s;
+ size_t url_l;
+ const char *realm = "";
+ const char *username = "";
+ const char *password = "";
+ const char *title;
+ char *description = NULL;
+ struct nsurl *siteurl = NULL;
+ const struct fetch_multipart_data *curmd; /* mutipart data iterator */
+
+ /* extract parameters from multipart post data */
+ curmd = ctx->multipart;
+ while (curmd != NULL) {
+ if (strcmp(curmd->name, "siteurl") == 0) {
+ res = nsurl_create(curmd->value, &siteurl);
+ if (res != NSERROR_OK) {
+ return fetch_about_srverror(ctx);
+ }
+ } else if (strcmp(curmd->name, "realm") == 0) {
+ realm = curmd->value;
+ } else if (strcmp(curmd->name, "username") == 0) {
+ username = curmd->value;
+ } else if (strcmp(curmd->name, "password") == 0) {
+ password = curmd->value;
+ }
+ curmd = curmd->next;
+ }
+
+ if (siteurl == NULL) {
+ return fetch_about_srverror(ctx);
+ }
+
+ /* content is going to return ok */
+ fetch_set_http_code(ctx->fetchh, 200);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/html; charset=utf-8")) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+
+ title = messages_get("LoginTitle");
+
+ res = ssenddataf(ctx,
+ "<html>\n<head>\n"
+ "<title>%s</title>\n"
+ "<link rel=\"stylesheet\" type=\"text/css\" "
+ "href=\"resource:internal.css\">\n"
+ "</head>\n"
+ "<body id =\"authentication\">\n"
+ "<h1>%s</h1>\n",
+ title, title);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<form method=\"post\""
+ " enctype=\"multipart/form-data\">");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = get_authentication_description(siteurl,
+ realm,
+ username,
+ password,
+ &description);
+ if (res == NSERROR_OK) {
+ res = ssenddataf(ctx, "<p>%s</p>", description);
+ free(description);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+ }
+
+ res = ssenddataf(ctx, "<table>");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<tr>"
+ "<th><label for=\"name\">%s:</label></th>"
+ "<td><input type=\"text\" id=\"username\" "
+ "name=\"username\" value=\"%s\"></td>"
+ "</tr>",
+ messages_get("Username"), username);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<tr>"
+ "<th><label for=\"password\">%s:</label></th>"
+ "<td><input type=\"password\" id=\"password\" "
+ "name=\"password\" value=\"%s\"></td>"
+ "</tr>",
+ messages_get("Password"), password);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx, "</table>");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<div id=\"buttons\">"
+ "<input type=\"submit\" id=\"login\" name=\"login\" "
+ "value=\"%s\" class=\"default-action\">"
+ "<input type=\"submit\" id=\"cancel\" name=\"cancel\" "
+ "value=\"%s\">"
+ "</div>",
+ messages_get("Login"),
+ messages_get("Cancel"));
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = nsurl_get(siteurl, NSURL_COMPLETE, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ url_s = strdup("");
+ }
+ res = ssenddataf(ctx,
+ "<input type=\"hidden\" name=\"siteurl\" value=\"%s\">",
+ url_s);
+ free(url_s);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<input type=\"hidden\" name=\"realm\" value=\"%s\">",
+ realm);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ res = ssenddataf(ctx, "</form></body>\n</html>\n");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_auth_handler_aborted;
+ }
+
+ fetch_about_send_finished(ctx);
+
+ nsurl_unref(siteurl);
+
+ return true;
+
+fetch_about_query_auth_handler_aborted:
+
+ nsurl_unref(siteurl);
+
+ return false;
+}
+
+
+/**
+ * generate the description of the privacy query
+ */
+static nserror get_privacy_description(struct nsurl *url, char **out_str)
+{
+ nserror res;
+ char *url_s;
+ size_t url_l;
+ char *str = NULL;
+ const char *key = "PrivacyDescription";
+
+ /* get the host in question */
+ res = nsurl_get(url, NSURL_HOST, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ /* obtain the description with the url substituted */
+ str = messages_get_buff(key, url_s);
+ if ((str != NULL) && (strcmp(key, str) == 0)) {
+ /* the returned string was simply the key */
+ free(str);
+ str = NULL;
+ }
+ if (str == NULL) {
+ /* failed to get suitable translated message text so
+ * fall back to basic english.
+ */
+ int slen;
+ slen = snprintf(str, 0, privacy_description_fallback, url_s) + 1;
+ str = malloc(slen);
+ if (str != NULL) {
+ snprintf(str, slen, privacy_description_fallback, url_s);
+ }
+ }
+
+ if (str == NULL) {
+ res = NSERROR_NOMEM;
+ } else {
+ *out_str = str;
+ }
+ free(url_s);
+
+ return res;
+}
+
+
+/**
+ * Handler to generate about scheme privacy query page
+ *
+ * \param ctx The fetcher context.
+ * \return true if handled false if aborted.
+ */
+static bool fetch_about_query_privacy_handler(struct fetch_about_context *ctx)
+{
+ nserror res;
+ char *url_s;
+ size_t url_l;
+ const char *reason = "";
+ const char *title;
+ struct nsurl *siteurl = NULL;
+ char *description = NULL;
+ const struct fetch_multipart_data *curmd; /* mutipart data iterator */
+
+ /* extract parameters from multipart post data */
+ curmd = ctx->multipart;
+ while (curmd != NULL) {
+ if (strcmp(curmd->name, "siteurl") == 0) {
+ res = nsurl_create(curmd->value, &siteurl);
+ if (res != NSERROR_OK) {
+ return fetch_about_srverror(ctx);
+ }
+ } else if (strcmp(curmd->name, "reason") == 0) {
+ reason = curmd->value;
+ }
+ curmd = curmd->next;
+ }
+
+ if (siteurl == NULL) {
+ return fetch_about_srverror(ctx);
+ }
+
+ /* content is going to return ok */
+ fetch_set_http_code(ctx->fetchh, 200);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/html; charset=utf-8")) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ title = messages_get("PrivacyTitle");
+ res = ssenddataf(ctx,
+ "<html>\n<head>\n"
+ "<title>%s</title>\n"
+ "<link rel=\"stylesheet\" type=\"text/css\" "
+ "href=\"resource:internal.css\">\n"
+ "</head>\n"
+ "<body id =\"privacy\">\n"
+ "<h1>%s</h1>\n",
+ title, title);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<form method=\"post\""
+ " enctype=\"multipart/form-data\">");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ res = get_privacy_description(siteurl, &description);
+ if (res == NSERROR_OK) {
+ res = ssenddataf(ctx, "<div><p>%s</p></div>", description);
+ free(description);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+ }
+ res = ssenddataf(ctx, "<div><p>%s</p></div>", reason);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ res = ssenddataf(ctx,
+ "<div id=\"buttons\">"
+ "<input type=\"submit\" id=\"back\" name=\"back\" "
+ "value=\"%s\" class=\"default-action\">"
+ "<input type=\"submit\" id=\"proceed\" name=\"proceed\" "
+ "value=\"%s\">"
+ "</div>",
+ messages_get("Backtosafety"),
+ messages_get("Proceed"));
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ res = nsurl_get(siteurl, NSURL_COMPLETE, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ url_s = strdup("");
+ }
+ res = ssenddataf(ctx,
+ "<input type=\"hidden\" name=\"siteurl\" value=\"%s\">",
+ url_s);
+ free(url_s);
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ res = ssenddataf(ctx, "</form></body>\n</html>\n");
+ if (res != NSERROR_OK) {
+ goto fetch_about_query_ssl_handler_aborted;
+ }
+
+ fetch_about_send_finished(ctx);
+
+ nsurl_unref(siteurl);
+
+ return true;
+
+fetch_about_query_ssl_handler_aborted:
+ nsurl_unref(siteurl);
+
+ return false;
+}
+
+
/* Forward declaration because this handler requires the handler table. */
static bool fetch_about_about_handler(struct fetch_about_context *ctx);
-struct about_handlers {
- const char *name; /**< name to match in url */
- int name_len;
- lwc_string *lname; /**< Interned name */
- fetch_about_handler handler; /* handler for the url */
- bool hidden; /* Flag indicating if entry should show in listing */
-};
-
-/** List of about paths and their handlers */
+/**
+ * List of about paths and their handlers
+ */
struct about_handlers about_handler_list[] = {
- { "credits", SLEN("credits"), NULL,
- fetch_about_credits_handler, false },
- { "licence", SLEN("licence"), NULL,
- fetch_about_licence_handler, false },
- { "license", SLEN("license"), NULL,
- fetch_about_licence_handler, true },
- { "welcome", SLEN("welcome"), NULL,
- fetch_about_welcome_handler, false },
- { "maps", SLEN("maps"), NULL,
- fetch_about_maps_handler, false },
- { "config", SLEN("config"), NULL,
- fetch_about_config_handler, false },
- { "Choices", SLEN("Choices"), NULL,
- fetch_about_choices_handler, false },
- { "testament", SLEN("testament"), NULL,
- fetch_about_testament_handler, false },
- { "about", SLEN("about"), NULL,
- fetch_about_about_handler, true },
- { "logo", SLEN("logo"), NULL,
- fetch_about_logo_handler, true },
- /* details about the image cache */
- { "imagecache", SLEN("imagecache"), NULL,
- fetch_about_imagecache_handler, true },
- /* The default blank page */
- { "blank", SLEN("blank"), NULL,
- fetch_about_blank_handler, true }
+ {
+ "credits",
+ SLEN("credits"),
+ NULL,
+ fetch_about_credits_handler,
+ false
+ },
+ {
+ "licence",
+ SLEN("licence"),
+ NULL,
+ fetch_about_licence_handler,
+ false
+ },
+ {
+ "license",
+ SLEN("license"),
+ NULL,
+ fetch_about_licence_handler,
+ true
+ },
+ {
+ "welcome",
+ SLEN("welcome"),
+ NULL,
+ fetch_about_welcome_handler,
+ false
+ },
+ {
+ "maps",
+ SLEN("maps"),
+ NULL,
+ fetch_about_maps_handler,
+ false
+ },
+ {
+ "config",
+ SLEN("config"),
+ NULL,
+ fetch_about_config_handler,
+ false
+ },
+ {
+ "Choices",
+ SLEN("Choices"),
+ NULL,
+ fetch_about_choices_handler,
+ false
+ },
+ {
+ "testament",
+ SLEN("testament"),
+ NULL,
+ fetch_about_testament_handler,
+ false
+ },
+ {
+ "about",
+ SLEN("about"),
+ NULL,
+ fetch_about_about_handler,
+ true
+ },
+ {
+ "logo",
+ SLEN("logo"),
+ NULL,
+ fetch_about_logo_handler,
+ true
+ },
+ {
+ /* details about the image cache */
+ "imagecache",
+ SLEN("imagecache"),
+ NULL,
+ fetch_about_imagecache_handler,
+ true
+ },
+ {
+ /* The default blank page */
+ "blank",
+ SLEN("blank"),
+ NULL,
+ fetch_about_blank_handler,
+ true
+ },
+ {
+ "query/auth",
+ SLEN("query/auth"),
+ NULL,
+ fetch_about_query_auth_handler,
+ true
+ },
+ {
+ "query/ssl",
+ SLEN("query/ssl"),
+ NULL,
+ fetch_about_query_privacy_handler,
+ true
+ }
};
-#define about_handler_list_len (sizeof(about_handler_list) / \
- sizeof(struct about_handlers))
+#define about_handler_list_len \
+ (sizeof(about_handler_list) / sizeof(struct about_handlers))
/**
* List all the valid about: paths available
@@ -624,24 +1225,17 @@ struct about_handlers about_handler_list[] = {
*/
static bool fetch_about_about_handler(struct fetch_about_context *ctx)
{
- fetch_msg msg;
- char buffer[1024];
- int code = 200;
- int slen;
+ nserror res;
unsigned int abt_loop = 0;
- int res = 0;
/* content is going to return ok */
- fetch_set_http_code(ctx->fetchh, code);
+ fetch_set_http_code(ctx->fetchh, 200);
/* content type */
if (fetch_about_send_header(ctx, "Content-Type: text/html"))
goto fetch_about_config_handler_aborted;
- msg.type = FETCH_DATA;
- msg.data.header_or_data.buf = (const uint8_t *) buffer;
-
- slen = snprintf(buffer, sizeof buffer,
+ res = ssenddataf(ctx,
"<html>\n<head>\n"
"<title>NetSurf List of About pages</title>\n"
"<link rel=\"stylesheet\" type=\"text/css\" "
@@ -654,6 +1248,9 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx)
"</p>\n"
"<h1>NetSurf List of About pages</h1>\n"
"<ul>\n");
+ if (res != NSERROR_OK) {
+ goto fetch_about_config_handler_aborted;
+ }
for (abt_loop = 0; abt_loop < about_handler_list_len; abt_loop++) {
@@ -661,34 +1258,21 @@ static bool fetch_about_about_handler(struct fetch_about_context *ctx)
if (about_handler_list[abt_loop].hidden)
continue;
- res = snprintf(buffer + slen, sizeof buffer - slen,
+ res = ssenddataf(ctx,
"<li><a href=\"about:%s\">about:%s</a></li>\n",
about_handler_list[abt_loop].name,
about_handler_list[abt_loop].name);
- if (res <= 0)
- break; /* last option */
-
- if (res >= (int)(sizeof buffer - slen)) {
- /* last entry would not fit in buffer, submit buffer */
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
- goto fetch_about_config_handler_aborted;
- slen = 0;
- } else {
- /* normal addition */
- slen += res;
+ if (res != NSERROR_OK) {
+ goto fetch_about_config_handler_aborted;
}
}
- slen += snprintf(buffer + slen, sizeof buffer - slen,
- "</ul>\n</body>\n</html>\n");
-
- msg.data.header_or_data.len = slen;
- if (fetch_about_send_callback(&msg, ctx))
+ res = ssenddataf(ctx, "</ul>\n</body>\n</html>\n");
+ if (res != NSERROR_OK) {
goto fetch_about_config_handler_aborted;
+ }
- msg.type = FETCH_FINISHED;
- fetch_about_send_callback(&msg, ctx);
+ fetch_about_send_finished(ctx);
return true;
@@ -697,7 +1281,9 @@ fetch_about_config_handler_aborted:
}
-/** callback to initialise the about fetcher. */
+/**
+ * callback to initialise the about scheme fetcher.
+ */
static bool fetch_about_initialise(lwc_string *scheme)
{
unsigned int abt_loop = 0;
@@ -718,7 +1304,10 @@ static bool fetch_about_initialise(lwc_string *scheme)
return true;
}
-/** callback to finalise the about fetcher. */
+
+/**
+ * callback to finalise the about scheme fetcher.
+ */
static void fetch_about_finalise(lwc_string *scheme)
{
unsigned int abt_loop = 0;
@@ -727,20 +1316,29 @@ static void fetch_about_finalise(lwc_string *scheme)
}
}
+
static bool fetch_about_can_fetch(const nsurl *url)
{
return true;
}
-/** callback to set up a about fetch context. */
+
+/**
+ * callback to set up a about scheme fetch.
+ *
+ * \param post_urlenc post data in urlenc format, owned by the llcache object
+ * hence valid the entire lifetime of the fetch.
+ * \param post_multipart post data in multipart format, owned by the llcache
+ * object hence valid the entire lifetime of the fetch.
+ */
static void *
fetch_about_setup(struct fetch *fetchh,
- nsurl *url,
- bool only_2xx,
- bool downgrade_tls,
- const char *post_urlenc,
- const struct fetch_multipart_data *post_multipart,
- const char **headers)
+ nsurl *url,
+ bool only_2xx,
+ bool downgrade_tls,
+ const char *post_urlenc,
+ const struct fetch_multipart_data *post_multipart,
+ const char **headers)
{
struct fetch_about_context *ctx;
unsigned int handler_loop;
@@ -769,13 +1367,17 @@ fetch_about_setup(struct fetch *fetchh,
ctx->fetchh = fetchh;
ctx->url = nsurl_ref(url);
+ ctx->multipart = post_multipart;
RING_INSERT(ring, ctx);
return ctx;
}
-/** callback to free a about fetch */
+
+/**
+ * callback to free a about scheme fetch
+ */
static void fetch_about_free(void *ctx)
{
struct fetch_about_context *c = ctx;
@@ -784,13 +1386,19 @@ static void fetch_about_free(void *ctx)
free(ctx);
}
-/** callback to start a about fetch */
+
+/**
+ * callback to start an about scheme fetch
+ */
static bool fetch_about_start(void *ctx)
{
return true;
}
-/** callback to abort a about fetch */
+
+/**
+ * callback to abort a about fetch
+ */
static void fetch_about_abort(void *ctx)
{
struct fetch_about_context *c = ctx;
@@ -803,7 +1411,9 @@ static void fetch_about_abort(void *ctx)
}
-/** callback to poll for additional about fetch contents */
+/**
+ * callback to poll for additional about fetch contents
+ */
static void fetch_about_poll(lwc_string *scheme)
{
struct fetch_about_context *c, *next;
@@ -844,6 +1454,7 @@ static void fetch_about_poll(lwc_string *scheme)
} while ( (c = next) != ring && ring != NULL);
}
+
nserror fetch_about_register(void)
{
lwc_string *scheme = lwc_string_ref(corestring_lwc_about);
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 7ce7c5b..50c5d64 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2006 Daniel Silverstone <dsilvers(a)digital-scurf.org>
+ * Copyright 2006-2019 Daniel Silverstone <dsilvers(a)digital-scurf.org>
+ * Copyright 2010-2018 Vincent Sanders <vince(a)netsurf-browser.org>
* Copyright 2007 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2003 Phil Mellor <monkeyson(a)users.sourceforge.net>
*
* This file is part of NetSurf.
*
@@ -39,6 +39,7 @@
#include <time.h>
#include <sys/stat.h>
#include <openssl/ssl.h>
+#include <openssl/x509v3.h>
#include <libwapcaplet/libwapcaplet.h>
#include <nsutils/time.h>
@@ -64,9 +65,6 @@
/** maximum number of progress notifications per second */
#define UPDATES_PER_SECOND 2
-/** maximum number of X509 certificates in chain for TLS connection */
-#define MAX_CERTS 10
-
/* the ciphersuites we are willing to use */
#define CIPHER_LIST \
/* disable everything */ \
@@ -109,7 +107,7 @@ struct curl_fetch_info {
struct curl_httppost *post_multipart; /**< Multipart post data, or 0. */
uint64_t last_progress_update; /**< Time of last progress update */
int cert_depth; /**< deepest certificate in use */
- struct cert_info cert_data[MAX_CERTS]; /**< HTTPS certificate data */
+ struct cert_info cert_data[MAX_SSL_CERTS]; /**< HTTPS certificate data */
};
/** curl handle cache entry */
@@ -142,6 +140,9 @@ static char fetch_error_buffer[CURL_ERROR_SIZE];
/** Proxy authentication details. */
static char fetch_proxy_userpwd[100];
+/** Interlock to prevent initiation during callbacks */
+static bool inside_curl = false;
+
/* OpenSSL 1.0.x to 1.1.0 certificate reference counting changed
* LibreSSL declares its OpenSSL version as 2.1 but only supports the old way
@@ -443,6 +444,175 @@ failed:
/**
+ * Report the certificate information in the fetch to the users
+ */
+static void
+fetch_curl_report_certs_upstream(struct curl_fetch_info *f)
+{
+ int depth;
+ BIO *mem;
+ BUF_MEM *buf;
+ const ASN1_INTEGER *asn1_num;
+ BIGNUM *bignum;
+ struct ssl_cert_info ssl_certs[MAX_SSL_CERTS];
+ fetch_msg msg;
+ struct cert_info *certs = f->cert_data;
+ memset(ssl_certs, 0, sizeof(ssl_certs));
+
+ for (depth = 0; depth <= f->cert_depth; depth++) {
+ assert(certs[depth].cert != NULL);
+
+ /* get certificate version */
+ ssl_certs[depth].version = X509_get_version(certs[depth].cert);
+
+ /* not before date */
+ mem = BIO_new(BIO_s_mem());
+ ASN1_TIME_print(mem, X509_get_notBefore(certs[depth].cert));
+ BIO_get_mem_ptr(mem, &buf);
+ (void) BIO_set_close(mem, BIO_NOCLOSE);
+ BIO_free(mem);
+ memcpy(ssl_certs[depth].not_before,
+ buf->data,
+ min(sizeof(ssl_certs[depth].not_before) - 1,
+ (unsigned)buf->length));
+ ssl_certs[depth].not_before[min(sizeof(ssl_certs[depth].not_before) - 1,
+ (unsigned)buf->length)] = 0;
+ BUF_MEM_free(buf);
+
+ /* not after date */
+ mem = BIO_new(BIO_s_mem());
+ ASN1_TIME_print(mem,
+ X509_get_notAfter(certs[depth].cert));
+ BIO_get_mem_ptr(mem, &buf);
+ (void) BIO_set_close(mem, BIO_NOCLOSE);
+ BIO_free(mem);
+ memcpy(ssl_certs[depth].not_after,
+ buf->data,
+ min(sizeof(ssl_certs[depth].not_after) - 1,
+ (unsigned)buf->length));
+ ssl_certs[depth].not_after[min(sizeof(ssl_certs[depth].not_after) - 1,
+ (unsigned)buf->length)] = 0;
+ BUF_MEM_free(buf);
+
+ /* signature type */
+ ssl_certs[depth].sig_type =
+ X509_get_signature_type(certs[depth].cert);
+
+ /* serial number */
+ asn1_num = X509_get_serialNumber(certs[depth].cert);
+ if (asn1_num != NULL) {
+ bignum = ASN1_INTEGER_to_BN(asn1_num, NULL);
+ if (bignum != NULL) {
+ char *tmp = BN_bn2hex(bignum);
+ if (tmp != NULL) {
+ strncpy(ssl_certs[depth].serialnum,
+ tmp,
+ sizeof(ssl_certs[depth].serialnum));
+ ssl_certs[depth].serialnum[sizeof(ssl_certs[depth].serialnum)-1] = '\0';
+ OPENSSL_free(tmp);
+ }
+ BN_free(bignum);
+ bignum = NULL;
+ }
+ }
+
+ /* issuer name */
+ mem = BIO_new(BIO_s_mem());
+ X509_NAME_print_ex(mem,
+ X509_get_issuer_name(certs[depth].cert),
+ 0, XN_FLAG_SEP_CPLUS_SPC |
+ XN_FLAG_DN_REV | XN_FLAG_FN_NONE);
+ BIO_get_mem_ptr(mem, &buf);
+ (void) BIO_set_close(mem, BIO_NOCLOSE);
+ BIO_free(mem);
+ memcpy(ssl_certs[depth].issuer,
+ buf->data,
+ min(sizeof(ssl_certs[depth].issuer) - 1,
+ (unsigned) buf->length));
+ ssl_certs[depth].issuer[min(sizeof(ssl_certs[depth].issuer) - 1,
+ (unsigned) buf->length)] = 0;
+ BUF_MEM_free(buf);
+
+ /* subject */
+ mem = BIO_new(BIO_s_mem());
+ X509_NAME_print_ex(mem,
+ X509_get_subject_name(certs[depth].cert),
+ 0,
+ XN_FLAG_SEP_CPLUS_SPC |
+ XN_FLAG_DN_REV |
+ XN_FLAG_FN_NONE);
+ BIO_get_mem_ptr(mem, &buf);
+ (void) BIO_set_close(mem, BIO_NOCLOSE);
+ BIO_free(mem);
+ memcpy(ssl_certs[depth].subject,
+ buf->data,
+ min(sizeof(ssl_certs[depth].subject) - 1,
+ (unsigned)buf->length));
+ ssl_certs[depth].subject[min(sizeof(ssl_certs[depth].subject) - 1,
+ (unsigned) buf->length)] = 0;
+ BUF_MEM_free(buf);
+
+ /* type of certificate */
+ ssl_certs[depth].cert_type =
+ X509_certificate_type(certs[depth].cert,
+ X509_get_pubkey(certs[depth].cert));
+
+ /* error code (if any) */
+ switch (certs[depth].err) {
+ case X509_V_OK:
+ ssl_certs[depth].err = SSL_CERT_ERR_OK;
+ break;
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ /* fallthrough */
+ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+ ssl_certs[depth].err = SSL_CERT_ERR_BAD_ISSUER;
+ break;
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+ /* fallthrough */
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+ /* fallthrough */
+ case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ /* fallthrough */
+ case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+ ssl_certs[depth].err = SSL_CERT_ERR_BAD_SIG;
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ /* fallthrough */
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ ssl_certs[depth].err = SSL_CERT_ERR_TOO_YOUNG;
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ /* fallthrough */
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ ssl_certs[depth].err = SSL_CERT_ERR_TOO_OLD;
+ break;
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ ssl_certs[depth].err = SSL_CERT_ERR_SELF_SIGNED;
+ break;
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ ssl_certs[depth].err = SSL_CERT_ERR_CHAIN_SELF_SIGNED;
+ break;
+ case X509_V_ERR_CERT_REVOKED:
+ ssl_certs[depth].err = SSL_CERT_ERR_REVOKED;
+ break;
+ case X509_V_ERR_HOSTNAME_MISMATCH:
+ ssl_certs[depth].err = SSL_CERT_ERR_HOSTNAME_MISMATCH;
+ break;
+ default:
+ ssl_certs[depth].err = SSL_CERT_ERR_UNKNOWN;
+ break;
+ }
+ }
+
+ msg.type = FETCH_CERTS;
+ msg.data.certs.certs = ssl_certs;
+ msg.data.certs.num_certs = depth;
+
+ fetch_send_callback(&msg, f->fetch_handle);
+}
+
+
+/**
* OpenSSL Certificate verification callback
*
* Called for each certificate in a chain being verified. OpenSSL
@@ -476,7 +646,7 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
}
/* certificate chain is excessively deep so fail verification */
- if (depth >= MAX_CERTS) {
+ if (depth >= MAX_SSL_CERTS) {
X509_STORE_CTX_set_error(x509_ctx,
X509_V_ERR_CERT_CHAIN_TOO_LONG);
return 0;
@@ -521,16 +691,30 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
*/
static int fetch_curl_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm)
{
+ struct curl_fetch_info *f = (struct curl_fetch_info *) parm;
int ok;
+ X509_VERIFY_PARAM *vparam;
+
+ /* Configure the verification parameters to include hostname */
+ vparam = X509_STORE_CTX_get0_param(x509_ctx);
+ X509_VERIFY_PARAM_set_hostflags(vparam, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+
+ ok = X509_VERIFY_PARAM_set1_host(vparam,
+ lwc_string_data(f->host),
+ lwc_string_length(f->host));
/* Store fetch struct in context for verify callback */
- ok = X509_STORE_CTX_set_app_data(x509_ctx, parm);
+ if (ok) {
+ ok = X509_STORE_CTX_set_app_data(x509_ctx, parm);
+ }
/* verify the certificate chain using standard call */
if (ok) {
ok = X509_verify_cert(x509_ctx);
}
+ fetch_curl_report_certs_upstream(f);
+
return ok;
}
@@ -710,6 +894,9 @@ fetch_curl_initiate_fetch(struct curl_fetch_info *fetch, CURL *handle)
code = fetch_curl_set_options(fetch);
if (code != CURLE_OK) {
fetch->curl_handle = 0;
+ /* The handle maybe went bad, eat it */
+ NSLOG(netsurf, WARNING, "cURL handle maybe went bad, retry later");
+ curl_easy_cleanup(handle);
return false;
}
@@ -747,6 +934,10 @@ static CURL *fetch_curl_get_handle(lwc_string *host)
static bool fetch_curl_start(void *vfetch)
{
struct curl_fetch_info *fetch = (struct curl_fetch_info*)vfetch;
+ if (inside_curl) {
+ NSLOG(netsurf, DEBUG, "Deferring fetch because we're inside cURL");
+ return false;
+ }
return fetch_curl_initiate_fetch(fetch,
fetch_curl_get_handle(fetch->host));
}
@@ -803,23 +994,6 @@ static void fetch_curl_cache_handle(CURL *handle, lwc_string *host)
/**
- * Abort a fetch.
- */
-static void fetch_curl_abort(void *vf)
-{
- struct curl_fetch_info *f = (struct curl_fetch_info *)vf;
- assert(f);
- NSLOG(netsurf, INFO, "fetch %p, url '%s'", f, nsurl_access(f->url));
- if (f->curl_handle) {
- f->abort = true;
- } else {
- fetch_remove_from_queues(f->fetch_handle);
- fetch_free(f->fetch_handle);
- }
-}
-
-
-/**
* Clean up the provided fetch object and free it.
*
* Will prod the queue afterwards to allow pending requests to be initiated.
@@ -846,6 +1020,30 @@ static void fetch_curl_stop(struct curl_fetch_info *f)
/**
+ * Abort a fetch.
+ */
+static void fetch_curl_abort(void *vf)
+{
+ struct curl_fetch_info *f = (struct curl_fetch_info *)vf;
+ assert(f);
+ NSLOG(netsurf, INFO, "fetch %p, url '%s'", f, nsurl_access(f->url));
+ if (f->curl_handle) {
+ if (inside_curl) {
+ NSLOG(netsurf, DEBUG, "Deferring cleanup");
+ f->abort = true;
+ } else {
+ NSLOG(netsurf, DEBUG, "Immediate abort");
+ fetch_curl_stop(f);
+ fetch_free(f->fetch_handle);
+ }
+ } else {
+ fetch_remove_from_queues(f->fetch_handle);
+ fetch_free(f->fetch_handle);
+ }
+}
+
+
+/**
* Free a fetch structure and associated resources.
*/
static void fetch_curl_free(void *vf)
@@ -869,7 +1067,7 @@ static void fetch_curl_free(void *vf)
curl_formfree(f->post_multipart);
}
- for (i = 0; i < MAX_CERTS && f->cert_data[i].cert; i++) {
+ for (i = 0; i < MAX_SSL_CERTS && f->cert_data[i].cert; i++) {
ns_X509_free(f->cert_data[i].cert);
}
@@ -938,114 +1136,6 @@ static bool fetch_curl_process_headers(struct curl_fetch_info *f)
return false;
}
-/**
- * setup callback to allow the user to examine certificates which have
- * failed to validate during fetch.
- */
-static void
-curl_start_cert_validate(struct curl_fetch_info *f,
- struct cert_info *certs)
-{
- int depth;
- BIO *mem;
- BUF_MEM *buf;
- struct ssl_cert_info ssl_certs[MAX_CERTS];
- fetch_msg msg;
-
- for (depth = 0; depth <= f->cert_depth; depth++) {
- assert(certs[depth].cert != NULL);
-
- /* get certificate version */
- ssl_certs[depth].version = X509_get_version(certs[depth].cert);
-
- /* not before date */
- mem = BIO_new(BIO_s_mem());
- ASN1_TIME_print(mem, X509_get_notBefore(certs[depth].cert));
- BIO_get_mem_ptr(mem, &buf);
- (void) BIO_set_close(mem, BIO_NOCLOSE);
- BIO_free(mem);
- memcpy(ssl_certs[depth].not_before,
- buf->data,
- min(sizeof(ssl_certs[depth].not_before) - 1,
- (unsigned)buf->length));
- ssl_certs[depth].not_before[min(sizeof(ssl_certs[depth].not_before) - 1,
- (unsigned)buf->length)] = 0;
- BUF_MEM_free(buf);
-
- /* not after date */
- mem = BIO_new(BIO_s_mem());
- ASN1_TIME_print(mem,
- X509_get_notAfter(certs[depth].cert));
- BIO_get_mem_ptr(mem, &buf);
- (void) BIO_set_close(mem, BIO_NOCLOSE);
- BIO_free(mem);
- memcpy(ssl_certs[depth].not_after,
- buf->data,
- min(sizeof(ssl_certs[depth].not_after) - 1,
- (unsigned)buf->length));
- ssl_certs[depth].not_after[min(sizeof(ssl_certs[depth].not_after) - 1,
- (unsigned)buf->length)] = 0;
- BUF_MEM_free(buf);
-
- /* signature type */
- ssl_certs[depth].sig_type =
- X509_get_signature_type(certs[depth].cert);
-
- /* serial number */
- ssl_certs[depth].serial =
- ASN1_INTEGER_get(
- X509_get_serialNumber(certs[depth].cert));
-
- /* issuer name */
- mem = BIO_new(BIO_s_mem());
- X509_NAME_print_ex(mem,
- X509_get_issuer_name(certs[depth].cert),
- 0, XN_FLAG_SEP_CPLUS_SPC |
- XN_FLAG_DN_REV | XN_FLAG_FN_NONE);
- BIO_get_mem_ptr(mem, &buf);
- (void) BIO_set_close(mem, BIO_NOCLOSE);
- BIO_free(mem);
- memcpy(ssl_certs[depth].issuer,
- buf->data,
- min(sizeof(ssl_certs[depth].issuer) - 1,
- (unsigned) buf->length));
- ssl_certs[depth].issuer[min(sizeof(ssl_certs[depth].issuer) - 1,
- (unsigned) buf->length)] = 0;
- BUF_MEM_free(buf);
-
- /* subject */
- mem = BIO_new(BIO_s_mem());
- X509_NAME_print_ex(mem,
- X509_get_subject_name(certs[depth].cert),
- 0,
- XN_FLAG_SEP_CPLUS_SPC |
- XN_FLAG_DN_REV |
- XN_FLAG_FN_NONE);
- BIO_get_mem_ptr(mem, &buf);
- (void) BIO_set_close(mem, BIO_NOCLOSE);
- BIO_free(mem);
- memcpy(ssl_certs[depth].subject,
- buf->data,
- min(sizeof(ssl_certs[depth].subject) - 1,
- (unsigned)buf->length));
- ssl_certs[depth].subject[min(sizeof(ssl_certs[depth].subject) - 1,
- (unsigned) buf->length)] = 0;
- BUF_MEM_free(buf);
-
- /* type of certificate */
- ssl_certs[depth].cert_type =
- X509_certificate_type(certs[depth].cert,
- X509_get_pubkey(certs[depth].cert));
-
- /* and clean up */
- ns_X509_free(certs[depth].cert);
- }
-
- msg.type = FETCH_CERT_ERR;
- msg.data.cert_err.certs = ssl_certs;
- msg.data.cert_err.num_certs = depth;
- fetch_send_callback(&msg, f->fetch_handle);
-}
/**
* Handle a completed fetch (CURLMSG_DONE from curl_multi_info_read()).
@@ -1062,7 +1152,6 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
struct curl_fetch_info *f;
char **_hideous_hack = (char **) (void *) &f;
CURLcode code;
- struct cert_info certs[MAX_CERTS];
/* find the structure associated with this fetch */
/* For some reason, cURL thinks CURLINFO_PRIVATE should be a string?! */
@@ -1106,13 +1195,11 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
*/
;
} else if (result == CURLE_SSL_PEER_CERTIFICATE ||
- result == CURLE_SSL_CACERT) {
- /* CURLE_SSL_PEER_CERTIFICATE renamed to
- * CURLE_PEER_FAILED_VERIFICATION
+ result == CURLE_SSL_CACERT) {
+ /* Some kind of failure has occurred. If we don't know
+ * what happened, we'll have reported unknown errors up
+ * to the user already via the certificate chain error fields.
*/
- memset(certs, 0, sizeof(certs));
- memcpy(certs, f->cert_data, sizeof(certs));
- memset(f->cert_data, 0, sizeof(f->cert_data));
cert = true;
} else {
NSLOG(netsurf, INFO, "Unknown cURL response code %d", result);
@@ -1129,7 +1216,9 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
fetch_send_callback(&msg, f->fetch_handle);
} else if (cert) {
/* user needs to validate certificate with issue */
- curl_start_cert_validate(f, certs);
+ fetch_msg msg;
+ msg.type = FETCH_CERT_ERR;
+ fetch_send_callback(&msg, f->fetch_handle);
} else if (error) {
fetch_msg msg;
switch (result) {
@@ -1205,6 +1294,7 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
}
/* do any possible work on the current fetches */
+ inside_curl = true;
do {
codem = curl_multi_perform(fetch_curl_multi, &running);
if (codem != CURLM_OK && codem != CURLM_CALL_MULTI_PERFORM) {
@@ -1228,6 +1318,7 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
}
curl_msg = curl_multi_info_read(fetch_curl_multi, &queue);
}
+ inside_curl = false;
}
@@ -1282,16 +1373,28 @@ fetch_curl_progress(void *clientp,
/**
- * Ignore everything given to it.
- *
- * Used to ignore cURL debug.
+ * Format curl debug for nslog
*/
-static int fetch_curl_ignore_debug(CURL *handle,
- curl_infotype type,
- char *data,
- size_t size,
- void *userptr)
+static int
+fetch_curl_debug(CURL *handle,
+ curl_infotype type,
+ char *data,
+ size_t size,
+ void *userptr)
{
+ static const char s_infotype[CURLINFO_END][3] = {
+ "* ", "< ", "> ", "{ ", "} ", "{ ", "} "
+ };
+ switch(type) {
+ case CURLINFO_TEXT:
+ case CURLINFO_HEADER_OUT:
+ case CURLINFO_HEADER_IN:
+ NSLOG(fetch, DEBUG, "%s%.*s", s_infotype[type], (int)size - 1, data);
+ break;
+
+ default:
+ break;
+ }
return 0;
}
@@ -1510,15 +1613,17 @@ nserror fetch_curl_register(void)
if (code != CURLE_OK) \
goto curl_easy_setopt_failed;
- if (verbose_log) {
- SETOPT(CURLOPT_VERBOSE, 1);
- } else {
- SETOPT(CURLOPT_VERBOSE, 0);
- }
SETOPT(CURLOPT_ERRORBUFFER, fetch_error_buffer);
+ SETOPT(CURLOPT_DEBUGFUNCTION, fetch_curl_debug);
if (nsoption_bool(suppress_curl_debug)) {
- SETOPT(CURLOPT_DEBUGFUNCTION, fetch_curl_ignore_debug);
+ SETOPT(CURLOPT_VERBOSE, 0);
+ } else {
+ SETOPT(CURLOPT_VERBOSE, 1);
}
+
+ /* Currently we explode if curl uses HTTP2, so force 1.1. */
+ SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+
SETOPT(CURLOPT_WRITEFUNCTION, fetch_curl_data);
SETOPT(CURLOPT_HEADERFUNCTION, fetch_curl_header);
SETOPT(CURLOPT_PROGRESSFUNCTION, fetch_curl_progress);
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index 5ba021f..8c04bcf 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -41,7 +41,7 @@
struct fetch_data_context {
struct fetch *parent_fetch;
- char *url;
+ nsurl *url;
char *mimetype;
char *data;
size_t datalen;
@@ -85,14 +85,7 @@ static void *fetch_data_setup(struct fetch *parent_fetch, nsurl *url,
return NULL;
ctx->parent_fetch = parent_fetch;
-
- /* TODO: keep as nsurl to avoid copy */
- ctx->url = malloc(nsurl_length(url) + 1);
- if (ctx->url == NULL) {
- free(ctx);
- return NULL;
- }
- memcpy(ctx->url, nsurl_access(url), nsurl_length(url) + 1);
+ ctx->url = nsurl_ref(url);
RING_INSERT(ring, ctx);
@@ -108,7 +101,7 @@ static void fetch_data_free(void *ctx)
{
struct fetch_data_context *c = ctx;
- free(c->url);
+ nsurl_unref(c->url);
free(c->data);
free(c->mimetype);
RING_REMOVE(ring, c);
@@ -138,8 +131,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
{
nserror res;
fetch_msg msg;
- char *params;
- char *comma;
+ const char *params;
+ const char *comma;
char *unescaped;
size_t unescaped_len;
@@ -149,9 +142,9 @@ static bool fetch_data_process(struct fetch_data_context *c)
* data must still be there.
*/
- NSLOG(netsurf, INFO, "url: %.140s", c->url);
+ NSLOG(netsurf, DEEPDEBUG, "url: %.140s", nsurl_access(c->url));
- if (strlen(c->url) < 6) {
+ if (nsurl_length(c->url) < 6) {
/* 6 is the minimum possible length (data:,) */
msg.type = FETCH_ERROR;
msg.data.error = "Malformed data: URL";
@@ -160,7 +153,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
}
/* skip the data: part */
- params = c->url + SLEN("data:");
+ params = nsurl_access(c->url) + SLEN("data:");
/* find the comma */
if ( (comma = strchr(params, ',')) == NULL) {
@@ -216,21 +209,12 @@ static bool fetch_data_process(struct fetch_data_context *c)
free(unescaped);
return false;
}
+ free(unescaped);
} else {
- c->data = malloc(unescaped_len);
- if (c->data == NULL) {
- msg.type = FETCH_ERROR;
- msg.data.error =
- "Unable to allocate memory for data: URL";
- fetch_data_send_callback(&msg, c);
- free(unescaped);
- return false;
- }
c->datalen = unescaped_len;
- memcpy(c->data, unescaped, unescaped_len);
+ c->data = unescaped;
}
- free(unescaped);
return true;
}
@@ -300,8 +284,8 @@ static void fetch_data_poll(lwc_string *scheme)
fetch_data_send_callback(&msg, c);
}
} else {
- NSLOG(netsurf, INFO, "Processing of %s failed!",
- c->url);
+ NSLOG(netsurf, INFO, "Processing of %.140s failed!",
+ nsurl_access(c->url));
/* Ensure that we're unlocked here. If we aren't,
* then fetch_data_process() is broken.
diff --git a/content/handlers/css/css.c b/content/handlers/css/css.c
index 93efd6a..af2a9bc 100644
--- a/content/handlers/css/css.c
+++ b/content/handlers/css/css.c
@@ -80,8 +80,6 @@ typedef struct {
* imports array */
} nscss_import_ctx;
-static bool nscss_process_data(struct content *c, const char *data,
- unsigned int size);
static bool nscss_convert(struct content *c);
static void nscss_destroy(struct content *c);
static nserror nscss_clone(const struct content *old, struct content **newc);
@@ -98,7 +96,7 @@ static void nscss_destroy_css_data(struct content_css_data *c);
static void nscss_content_done(struct content_css_data *css, void *pw);
static css_error nscss_handle_import(void *pw, css_stylesheet *parent,
- lwc_string *url, uint64_t media);
+ lwc_string *url);
static nserror nscss_import(hlcache_handle *handle,
const hlcache_event *event, void *pw);
static css_error nscss_import_complete(nscss_import_ctx *ctx);
@@ -170,7 +168,7 @@ nscss_create(const content_handler *handler,
xnsbase, charset, result->base.quirks,
nscss_content_done, result);
if (error != NSERROR_OK) {
- content_broadcast_errorcode(&result->base, NSERROR_NOMEM);
+ content_broadcast_error(&result->base, NSERROR_NOMEM, NULL);
if (charset_value != NULL)
lwc_string_unref(charset_value);
free(result);
@@ -245,14 +243,15 @@ static nserror nscss_create_css_data(struct content_css_data *c,
* \param size Number of bytes to process
* \return true on success, false on failure
*/
-bool nscss_process_data(struct content *c, const char *data, unsigned int size)
+static bool
+nscss_process_data(struct content *c, const char *data, unsigned int size)
{
nscss_content *css = (nscss_content *) c;
css_error error;
error = nscss_process_css_data(&css->data, data, size);
if (error != CSS_OK && error != CSS_NEEDDATA) {
- content_broadcast_errorcode(c, NSERROR_CSS);
+ content_broadcast_error(c, NSERROR_CSS, NULL);
}
return (error == CSS_OK || error == CSS_NEEDDATA);
@@ -286,7 +285,7 @@ bool nscss_convert(struct content *c)
error = nscss_convert_css_data(&css->data);
if (error != CSS_OK) {
- content_broadcast_errorcode(c, NSERROR_CSS);
+ content_broadcast_error(c, NSERROR_CSS, NULL);
return false;
}
@@ -374,8 +373,8 @@ nserror nscss_clone(const struct content *old, struct content **newc)
{
const nscss_content *old_css = (const nscss_content *) old;
nscss_content *new_css;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
nserror error;
new_css = calloc(1, sizeof(nscss_content));
@@ -402,7 +401,9 @@ nserror nscss_clone(const struct content *old, struct content **newc)
data = content__get_source_data(&new_css->base, &size);
if (size > 0) {
- if (nscss_process_data(&new_css->base, data, size) == false) {
+ if (nscss_process_data(&new_css->base,
+ (char *)data,
+ (unsigned int)size) == false) {
content_destroy(&new_css->base);
return NSERROR_CLONE_FAILED;
}
@@ -479,7 +480,7 @@ void nscss_content_done(struct content_css_data *css, void *pw)
/* Retrieve the size of this sheet */
error = css_stylesheet_size(css->sheet, &size);
if (error != CSS_OK) {
- content_broadcast_errorcode(c, NSERROR_CSS);
+ content_broadcast_error(c, NSERROR_CSS, NULL);
content_set_error(c);
return;
}
@@ -512,11 +513,10 @@ void nscss_content_done(struct content_css_data *css, void *pw)
* \param pw CSS object requesting the import
* \param parent Stylesheet requesting the import
* \param url URL of the imported sheet
- * \param media Applicable media for the imported sheet
* \return CSS_OK on success, appropriate error otherwise
*/
css_error nscss_handle_import(void *pw, css_stylesheet *parent,
- lwc_string *url, uint64_t media)
+ lwc_string *url)
{
content_type accept = CONTENT_CSS;
struct content_css_data *c = pw;
@@ -562,7 +562,6 @@ css_error nscss_handle_import(void *pw, css_stylesheet *parent,
}
/* Create content */
- c->imports[c->import_count].media = media;
/** \todo Why aren't we getting a relative url part, to join? */
nerror = nsurl_create(lwc_string_data(url), &ns_url);
@@ -635,7 +634,6 @@ nserror nscss_import(hlcache_handle *handle,
error = nscss_import_complete(ctx);
break;
- case CONTENT_MSG_ERRORCODE:
case CONTENT_MSG_ERROR:
hlcache_handle_release(handle);
ctx->css->imports[ctx->index].c = NULL;
@@ -643,7 +641,6 @@ nserror nscss_import(hlcache_handle *handle,
error = nscss_import_complete(ctx);
/* Already released handle */
break;
-
default:
break;
}
diff --git a/content/handlers/css/css.h b/content/handlers/css/css.h
index 4b38829..5e2b64a 100644
--- a/content/handlers/css/css.h
+++ b/content/handlers/css/css.h
@@ -32,7 +32,6 @@ struct hlcache_handle;
*/
struct nscss_import {
struct hlcache_handle *c; /**< Content containing sheet */
- uint64_t media; /**< Media types that sheet applies to */
};
/**
diff --git a/content/handlers/css/hints.c b/content/handlers/css/hints.c
index 3a15f8e..adfdd01 100644
--- a/content/handlers/css/hints.c
+++ b/content/handlers/css/hints.c
@@ -607,12 +607,12 @@ static void css_hint_clean(void)
hint_ctx.len = 0;
}
-static inline struct css_hint * css_hint_advance(struct css_hint *hint)
+static inline void css_hint_advance(struct css_hint **hint)
{
hint_ctx.len++;
assert(hint_ctx.len < MAX_HINTS_PER_ELEMENT);
- return ++hint;
+ (*hint)++;
}
static void css_hint_get_hints(struct css_hint **hints, uint32_t *nhints)
@@ -671,7 +671,7 @@ static void css_hint_table_cell_border_padding(
hint_prop++) {
hint->prop = hint_prop;
hint->status = CSS_BORDER_STYLE_INSET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
for (hint_prop = CSS_PROP_BORDER_TOP_WIDTH;
@@ -681,7 +681,7 @@ static void css_hint_table_cell_border_padding(
hint->data.length.value = INTTOFIX(1);
hint->data.length.unit = CSS_UNIT_PX;
hint->status = CSS_BORDER_WIDTH_WIDTH;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -704,7 +704,7 @@ static void css_hint_table_cell_border_padding(
hint->prop = hint_prop;
hint->data.color = hint_color;
hint->status = CSS_BORDER_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -729,7 +729,7 @@ static void css_hint_table_cell_border_padding(
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_PADDING_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -754,25 +754,25 @@ static void css_hint_vertical_align_table_cells(
corestring_lwc_top)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_TOP;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_middle)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_bottom)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_BOTTOM;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_baseline)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -794,7 +794,7 @@ static void css_hint_vertical_align_replaced(
corestring_lwc_top)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_TOP;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_bottom) ||
@@ -802,13 +802,13 @@ static void css_hint_vertical_align_replaced(
corestring_lwc_baseline)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_texttop)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_absmiddle) ||
@@ -816,7 +816,7 @@ static void css_hint_vertical_align_replaced(
corestring_lwc_abscenter)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -837,25 +837,25 @@ static void css_hint_text_align_normal(
corestring_lwc_left)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_LEFT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_center)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_CENTER;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_right)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_RIGHT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_justify)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(align);
}
@@ -869,7 +869,7 @@ static void css_hint_text_align_center(
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
static void css_hint_margin_left_right_align_center(
@@ -895,11 +895,11 @@ static void css_hint_margin_left_right_align_center(
corestring_lwc_absmiddle)) {
hint->prop = CSS_PROP_MARGIN_LEFT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_RIGHT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -921,25 +921,25 @@ static void css_hint_text_align_special(
corestring_lwc_center)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_left)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_right)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_justify)) {
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(align);
}
@@ -953,7 +953,7 @@ static void css_hint_text_align_table_special(
hint->prop = CSS_PROP_TEXT_ALIGN;
hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
static void css_hint_margin_hspace_vspace(
@@ -977,13 +977,13 @@ static void css_hint_margin_hspace_vspace(
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_BOTTOM;
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1001,13 +1001,13 @@ static void css_hint_margin_hspace_vspace(
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_RIGHT;
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1032,33 +1032,33 @@ static void css_hint_margin_left_right_hr(
hint->data.length.value = 0;
hint->data.length.unit = CSS_UNIT_PX;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_RIGHT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_center)) {
hint->prop = CSS_PROP_MARGIN_LEFT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_RIGHT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_right)) {
hint->prop = CSS_PROP_MARGIN_LEFT;
hint->status = CSS_MARGIN_AUTO;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
hint->prop = CSS_PROP_MARGIN_RIGHT;
hint->data.length.value = 0;
hint->data.length.unit = CSS_UNIT_PX;
hint->status = CSS_MARGIN_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1083,7 +1083,7 @@ static void css_hint_table_spacing_border(
hint_prop++) {
hint->prop = hint_prop;
hint->status = CSS_BORDER_STYLE_OUTSET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
if (parse_dimension(
@@ -1098,7 +1098,7 @@ static void css_hint_table_spacing_border(
hint->data.length.value = hint_length.value;
hint->data.length.unit = hint_length.unit;
hint->status = CSS_BORDER_WIDTH_WIDTH;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -1121,7 +1121,7 @@ static void css_hint_table_spacing_border(
hint->prop = hint_prop;
hint->data.color = hint_color;
hint->status = CSS_BORDER_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -1138,7 +1138,7 @@ static void css_hint_table_spacing_border(
hint->prop = CSS_PROP_BORDER_SPACING;
hint->data.position.v = hint->data.position.h;
hint->status = CSS_BORDER_SPACING_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1162,7 +1162,7 @@ static void css_hint_height(
&hint->data.length.unit)) {
hint->prop = CSS_PROP_HEIGHT;
hint->status = CSS_HEIGHT_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1186,7 +1186,7 @@ static void css_hint_width(
&hint->data.length.unit)) {
hint->prop = CSS_PROP_WIDTH;
hint->status = CSS_WIDTH_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1211,7 +1211,7 @@ static void css_hint_height_width_textarea(
hint->prop = CSS_PROP_HEIGHT;
hint->data.length.unit = CSS_UNIT_EM;
hint->status = CSS_HEIGHT_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1227,7 +1227,7 @@ static void css_hint_height_width_textarea(
hint->prop = CSS_PROP_WIDTH;
hint->data.length.unit = CSS_UNIT_EX;
hint->status = CSS_WIDTH_SET;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(attr);
}
@@ -1276,7 +1276,7 @@ static void css_hint_width_input(
if (attr2 != NULL) {
dom_string_unref(attr2);
}
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
dom_string_unref(attr);
@@ -1329,7 +1329,7 @@ static void css_hint_anchor_color(
&hint->data.color)) {
hint->prop = CSS_PROP_COLOR;
hint->status = CSS_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(color);
}
@@ -1351,7 +1351,7 @@ static void css_hint_body_color(
&hint->data.color)) {
hint->prop = CSS_PROP_COLOR;
hint->status = CSS_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(color);
}
@@ -1373,7 +1373,7 @@ static void css_hint_color(
&hint->data.color)) {
hint->prop = CSS_PROP_COLOR;
hint->status = CSS_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(color);
}
@@ -1395,7 +1395,7 @@ static void css_hint_font_size(
&hint->data.length.value,
&hint->data.length.unit)) {
hint->prop = CSS_PROP_FONT_SIZE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(size);
}
@@ -1415,13 +1415,13 @@ static void css_hint_float(
corestring_lwc_left)) {
hint->prop = CSS_PROP_FLOAT;
hint->status = CSS_FLOAT_LEFT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
} else if (dom_string_caseless_lwc_isequal(align,
corestring_lwc_right)) {
hint->prop = CSS_PROP_FLOAT;
hint->status = CSS_FLOAT_RIGHT;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(align);
}
@@ -1441,7 +1441,7 @@ static void css_hint_caption_side(
corestring_lwc_bottom)) {
hint->prop = CSS_PROP_CAPTION_SIDE;
hint->status = CSS_CAPTION_SIDE_BOTTOM;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(align);
}
@@ -1463,7 +1463,7 @@ static void css_hint_bg_color(
&hint->data.color)) {
hint->prop = CSS_PROP_BACKGROUND_COLOR;
hint->status = CSS_BACKGROUND_COLOR_COLOR;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
dom_string_unref(bgcolor);
}
@@ -1495,7 +1495,7 @@ static void css_hint_bg_image(
hint->prop = CSS_PROP_BACKGROUND_IMAGE;
hint->data.string = iurl;
hint->status = CSS_BACKGROUND_IMAGE_IMAGE;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
}
@@ -1513,7 +1513,7 @@ static void css_hint_white_space_nowrap(
if (err == DOM_NO_ERR && nowrap == true) {
hint->prop = CSS_PROP_WHITE_SPACE;
hint->status = CSS_WHITE_SPACE_NOWRAP;
- hint = css_hint_advance(hint);
+ css_hint_advance(&hint);
}
}
@@ -1538,22 +1538,22 @@ css_error node_presentational_hint(void *pw, void *node,
css_hint_width(pw, node);
css_hint_table_cell_border_padding(pw, node);
css_hint_white_space_nowrap(pw, node);
- /* fallthrough */
+ /* fall through */
case DOM_HTML_ELEMENT_TYPE_TR:
css_hint_height(pw, node);
- /* fallthrough */
+ /* fall through */
case DOM_HTML_ELEMENT_TYPE_THEAD:
case DOM_HTML_ELEMENT_TYPE_TBODY:
case DOM_HTML_ELEMENT_TYPE_TFOOT:
css_hint_text_align_special(pw, node);
- /* fallthrough */
+ /* fall through */
case DOM_HTML_ELEMENT_TYPE_COL:
css_hint_vertical_align_table_cells(pw, node);
break;
case DOM_HTML_ELEMENT_TYPE_APPLET:
case DOM_HTML_ELEMENT_TYPE_IMG:
css_hint_margin_hspace_vspace(pw, node);
- /* fallthrough */
+ /* fall through */
case DOM_HTML_ELEMENT_TYPE_EMBED:
case DOM_HTML_ELEMENT_TYPE_IFRAME:
case DOM_HTML_ELEMENT_TYPE_OBJECT:
@@ -1576,7 +1576,7 @@ css_error node_presentational_hint(void *pw, void *node,
break;
case DOM_HTML_ELEMENT_TYPE_CAPTION:
css_hint_caption_side(pw, node);
- /* fallthrough */
+ /* fall through */
case DOM_HTML_ELEMENT_TYPE_DIV:
css_hint_text_align_special(pw, node);
break;
diff --git a/content/handlers/css/select.c b/content/handlers/css/select.c
index ee79eb3..99840e9 100644
--- a/content/handlers/css/select.c
+++ b/content/handlers/css/select.c
@@ -255,7 +255,7 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
* or NULL on failure
*/
css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
- uint64_t media, const css_stylesheet *inline_style)
+ const css_media *media, const css_stylesheet *inline_style)
{
css_computed_style *composed;
css_select_results *styles;
diff --git a/content/handlers/css/select.h b/content/handlers/css/select.h
index 9fa6d3a..b45d1ed 100644
--- a/content/handlers/css/select.h
+++ b/content/handlers/css/select.h
@@ -45,7 +45,7 @@ css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len,
const char *charset, const char *url, bool allow_quirks);
css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
- uint64_t media, const css_stylesheet *inline_style);
+ const css_media *media, const css_stylesheet *inline_style);
css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
const css_computed_style *parent);
diff --git a/content/handlers/css/utils.c b/content/handlers/css/utils.c
index 8fe157b..cf48e89 100644
--- a/content/handlers/css/utils.c
+++ b/content/handlers/css/utils.c
@@ -27,6 +27,8 @@
/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
css_fixed nscss_screen_dpi = F_90;
+/** Medium screen density for device viewing distance. */
+css_fixed nscss_baseline_pixel_density = F_96;
/**
* Map viewport-relative length units to either vh or vw.
@@ -100,7 +102,7 @@ css_fixed nscss_len2pt(
switch (unit) {
/* We assume the screen and any other output has the same dpi */
/* 1in = DPIpx => 1px = (72/DPI)pt */
- case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi);
+ case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), F_96);
/* 1in = 72pt */
case CSS_UNIT_IN: return FMUL(length, F_72);
/* 1in = 2.54cm => 1cm = (72/2.54)pt */
@@ -115,10 +117,8 @@ css_fixed nscss_len2pt(
case CSS_UNIT_PT: return length;
/* 1pc = 12pt */
case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
- case CSS_UNIT_VH: return FDIV(FMUL(FDIV((length * ctx->vh), F_100),
- F_72), nscss_screen_dpi);
- case CSS_UNIT_VW: return FDIV(FMUL(FDIV((length * ctx->vw), F_100),
- F_72), nscss_screen_dpi);
+ case CSS_UNIT_VH: return FDIV(FMUL(FDIV(FMUL(length, ctx->vh), F_100), F_72), F_96);
+ case CSS_UNIT_VW: return FDIV(FMUL(FDIV(FMUL(length,ctx->vw), F_100), F_72), F_96);
default: break;
}
@@ -161,7 +161,7 @@ css_fixed nscss_len2px(
/* Convert to pixels (manually, to maximise precision)
* 1in = 72pt => 1pt = (DPI/72)px */
- px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
+ px_per_unit = FDIV(FMUL(font_size, F_96), F_72);
/* Scale non-em units to em. We have fixed ratios. */
switch (unit) {
@@ -184,29 +184,29 @@ css_fixed nscss_len2px(
case CSS_UNIT_PX:
px_per_unit = F_1;
break;
- /* 1in = DPIpx */
+ /* 1in = 96 CSS pixels */
case CSS_UNIT_IN:
- px_per_unit = nscss_screen_dpi;
+ px_per_unit = F_96;
break;
/* 1in = 2.54cm => 1cm = (DPI/2.54)px */
case CSS_UNIT_CM:
- px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54));
+ px_per_unit = FDIV(F_96, FLTTOFIX(2.54));
break;
/* 1in = 25.4mm => 1mm = (DPI/25.4)px */
case CSS_UNIT_MM:
- px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4));
+ px_per_unit = FDIV(F_96, FLTTOFIX(25.4));
break;
/* 1in = 101.6q => 1q = (DPI/101.6)px */
case CSS_UNIT_Q:
- px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(101.6));
+ px_per_unit = FDIV(F_96, FLTTOFIX(101.6));
break;
/* 1in = 72pt => 1pt = (DPI/72)px */
case CSS_UNIT_PT:
- px_per_unit = FDIV(nscss_screen_dpi, F_72);
+ px_per_unit = FDIV(F_96, F_72);
break;
/* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */
case CSS_UNIT_PC:
- px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6));
+ px_per_unit = FDIV(F_96, INTTOFIX(6));
break;
case CSS_UNIT_REM:
{
@@ -228,24 +228,28 @@ css_fixed nscss_len2px(
/* Convert to pixels (manually, to maximise precision)
* 1in = 72pt => 1pt = (DPI/72)px */
- px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
+ px_per_unit = FDIV(FMUL(font_size, F_96), F_72);
break;
}
/* 1rlh = <user_font_size>pt => 1rlh = (DPI/user_font_size)px */
case CSS_UNIT_RLH:
- px_per_unit = FDIV(nscss_screen_dpi, FDIV(
+ px_per_unit = FDIV(F_96, FDIV(
INTTOFIX(nsoption_int(font_size)),
INTTOFIX(10)));
break;
case CSS_UNIT_VH:
- return TRUNCATEFIX((FDIV((length * ctx->vh), F_100) + F_0_5));
+ px_per_unit = FDIV(ctx->vh, F_100);
+ break;
case CSS_UNIT_VW:
- return TRUNCATEFIX((FDIV((length * ctx->vw), F_100) + F_0_5));
+ px_per_unit = FDIV(ctx->vw, F_100);
+ break;
default:
px_per_unit = 0;
break;
}
+ px_per_unit = nscss_pixels_css_to_physical(px_per_unit);
+
/* Ensure we round px_per_unit to the nearest whole number of pixels:
* the use of FIXTOINT() below will truncate. */
px_per_unit += F_0_5;
diff --git a/content/handlers/css/utils.h b/content/handlers/css/utils.h
index c8f4c82..e35a660 100644
--- a/content/handlers/css/utils.h
+++ b/content/handlers/css/utils.h
@@ -26,6 +26,9 @@
/** DPI of the screen, in fixed point units */
extern css_fixed nscss_screen_dpi;
+/** Medium screen density for device viewing distance. */
+extern css_fixed nscss_baseline_pixel_density;
+
/**
* Length conversion context data.
*/
@@ -76,6 +79,31 @@ css_fixed nscss_len2px(
css_unit unit,
const css_computed_style *style);
+/**
+ * Convert css pixels to physical pixels.
+ *
+ * \param[in] css_pixels Length in css pixels.
+ * \return length in physical pixels
+ */
+static inline css_fixed nscss_pixels_css_to_physical(
+ css_fixed css_pixels)
+{
+ return FDIV(FMUL(css_pixels, nscss_screen_dpi),
+ nscss_baseline_pixel_density);
+}
+
+/**
+ * Convert physical pixels to css pixels.
+ *
+ * \param[in] physical_pixels Length in physical pixels.
+ * \return length in css pixels
+ */
+static inline css_fixed nscss_pixels_physical_to_css(
+ css_fixed physical_pixels)
+{
+ return FDIV(FMUL(physical_pixels, nscss_baseline_pixel_density),
+ nscss_screen_dpi);
+}
/**
* Temporary helper wrappers for for libcss computed style getter, while
diff --git a/content/handlers/html/box.c b/content/handlers/html/box.c
index 52cf124..30cb4e2 100644
--- a/content/handlers/html/box.c
+++ b/content/handlers/html/box.c
@@ -307,11 +307,11 @@ void box_coords(struct box *box, int *x, int *y)
*y = box->y;
while (box->parent) {
if (box_is_float(box)) {
- do {
- box = box->parent;
- } while (!box->float_children);
- } else
+ assert(box->float_container);
+ box = box->float_container;
+ } else {
box = box->parent;
+ }
*x += box->x - scrollbar_get_offset(box->scroll_x);
*y += box->y - scrollbar_get_offset(box->scroll_y);
}
@@ -505,7 +505,7 @@ static inline struct box *box_move_xy(struct box *b, enum box_walk_dir dir,
rb = b;
break;
}
- /* Fall through */
+ /* fall through */
case BOX_WALK_NEXT_SIBLING:
do {
diff --git a/content/handlers/html/box.h b/content/handlers/html/box.h
index 0952b84..089c664 100644
--- a/content/handlers/html/box.h
+++ b/content/handlers/html/box.h
@@ -359,7 +359,8 @@ bool box_vscrollbar_present(const struct box *box);
bool box_hscrollbar_present(const struct box *box);
nserror dom_to_box(struct dom_node *n, struct html_content *c,
- box_construct_complete_cb cb);
+ box_construct_complete_cb cb, void **box_conversion_context);
+nserror cancel_dom_to_box(void *box_conversion_context);
bool box_normalise_block(
struct box *block,
@@ -377,4 +378,12 @@ static inline bool box_is_first_child(struct box *b)
return (b->parent == NULL || b == b->parent->children);
}
+/**
+ * Retrieve the box for a dom node, if there is one
+ *
+ * \param node The DOM node
+ * \return The box if there is one
+ */
+struct box *box_for_node(struct dom_node *node);
+
#endif
diff --git a/content/handlers/html/box_construct.c b/content/handlers/html/box_construct.c
index 5650fbf..f0d68ac 100644
--- a/content/handlers/html/box_construct.c
+++ b/content/handlers/html/box_construct.c
@@ -144,7 +144,6 @@ static const struct element_entry element_table[] = {
{"embed", box_embed},
{"frameset", box_frameset},
{"iframe", box_iframe},
- {"image", box_image},
{"img", box_image},
{"input", box_input},
{"noscript", box_noscript},
@@ -164,10 +163,12 @@ static const struct element_entry element_table[] = {
* \return netsurf error code indicating status of call
*/
-nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb)
+nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb, void **box_conversion_context)
{
struct box_construct_ctx *ctx;
+ assert(box_conversion_context != NULL);
+
if (c->bctx == NULL) {
/* create a context allocation for this box tree */
c->bctx = talloc_zero(0, int);
@@ -187,9 +188,28 @@ nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb)
ctx->cb = cb;
ctx->bctx = c->bctx;
+ *box_conversion_context = ctx;
+
return guit->misc->schedule(0, (void *)convert_xml_to_box, ctx);
}
+nserror cancel_dom_to_box(void *box_conversion_context)
+{
+ struct box_construct_ctx *ctx = box_conversion_context;
+ nserror err;
+
+ err = guit->misc->schedule(-1, (void *)convert_xml_to_box, ctx);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ dom_node_unref(ctx->n);
+ free(ctx);
+
+ return NSERROR_OK;
+}
+
+
/* mapping from CSS display to box type
* this table must be in sync with libcss' css_display enum */
static const box_type box_map[] = {
@@ -212,7 +232,8 @@ static const box_type box_map[] = {
BOX_NONE /*CSS_DISPLAY_NONE*/
};
-static inline struct box *box_for_node(dom_node *n)
+/* Exported function, see box.h */
+struct box *box_for_node(dom_node *n)
{
struct box *box = NULL;
dom_exception err;
@@ -1374,7 +1395,7 @@ css_select_results *box_get_style(html_content *c,
ctx.parent_style = parent_style;
/* Select style for element */
- styles = nscss_get_style(&ctx, n, CSS_MEDIA_SCREEN, inline_style);
+ styles = nscss_get_style(&ctx, n, &c->media, inline_style);
/* No longer need inline style */
if (inline_style != NULL)
@@ -2230,8 +2251,13 @@ bool box_create_frameset(struct content_html_frames *f, dom_node *n,
dom_string_unref(s);
}
- dom_element_has_attribute(c, corestring_dom_noresize,
- &frame->no_resize);
+ if (dom_element_has_attribute(c, corestring_dom_noresize,
+ &frame->no_resize) != DOM_NO_ERR) {
+ /* If we can't read the attribute for some reason,
+ * assume we didn't have it.
+ */
+ frame->no_resize = false;
+ }
err = dom_element_get_attribute(c, corestring_dom_frameborder,
&s);
@@ -2476,49 +2502,57 @@ static bool box_input_text(html_content *html, struct box *box,
bool box_input(BOX_SPECIAL_PARAMS)
{
- struct form_control *gadget = NULL;
+ struct form_control *gadget;
dom_string *type = NULL;
dom_exception err;
nsurl *url;
nserror error;
- dom_element_get_attribute(n, corestring_dom_type, &type);
-
gadget = html_forms_get_control_for_node(content->forms, n);
- if (gadget == NULL)
- goto no_memory;
+ if (gadget == NULL) {
+ return false;
+ }
+
box->gadget = gadget;
box->flags |= IS_REPLACED;
gadget->box = box;
gadget->html = content;
- if (type && dom_string_caseless_lwc_isequal(type,
- corestring_lwc_password)) {
+ /* get entry type */
+ err = dom_element_get_attribute(n, corestring_dom_type, &type);
+ if ((err != DOM_NO_ERR) || (type == NULL)) {
+ /* no type so "text" is assumed */
+ if (box_input_text(content, box, n) == false) {
+ return false;
+ }
+ *convert_children = false;
+ return true;
+ }
+
+
+ if (dom_string_caseless_lwc_isequal(type, corestring_lwc_password)) {
if (box_input_text(content, box, n) == false)
goto no_memory;
- } else if (type && dom_string_caseless_lwc_isequal(type,
- corestring_lwc_file)) {
+ } else if (dom_string_caseless_lwc_isequal(type, corestring_lwc_file)) {
box->type = BOX_INLINE_BLOCK;
- } else if (type && dom_string_caseless_lwc_isequal(type,
+ } else if (dom_string_caseless_lwc_isequal(type,
corestring_lwc_hidden)) {
/* no box for hidden inputs */
box->type = BOX_NONE;
- } else if (type &&
- (dom_string_caseless_lwc_isequal(type,
+ } else if ((dom_string_caseless_lwc_isequal(type,
corestring_lwc_checkbox) ||
dom_string_caseless_lwc_isequal(type,
corestring_lwc_radio))) {
- } else if (type &&
- (dom_string_caseless_lwc_isequal(type,
+ } else if (dom_string_caseless_lwc_isequal(type,
corestring_lwc_submit) ||
dom_string_caseless_lwc_isequal(type,
corestring_lwc_reset) ||
dom_string_caseless_lwc_isequal(type,
- corestring_lwc_button))) {
+ corestring_lwc_button)) {
struct box *inline_container, *inline_box;
if (box_button(n, content, box, 0) == false)
@@ -2560,11 +2594,12 @@ bool box_input(BOX_SPECIAL_PARAMS)
box_add_child(box, inline_container);
- } else if (type && dom_string_caseless_lwc_isequal(type,
+ } else if (dom_string_caseless_lwc_isequal(type,
corestring_lwc_image)) {
gadget->type = GADGET_IMAGE;
- if (box->style && ns_computed_display(box->style,
+ if (box->style &&
+ ns_computed_display(box->style,
box_is_root(n)) != CSS_DISPLAY_NONE &&
nsoption_bool(foreground_images) == true) {
dom_string *s;
@@ -2595,20 +2630,19 @@ bool box_input(BOX_SPECIAL_PARAMS)
}
}
} else {
- /* the default type is "text" */
+ /* unhandled type the default is "text" */
if (box_input_text(content, box, n) == false)
goto no_memory;
}
- if (type)
- dom_string_unref(type);
+ dom_string_unref(type);
*convert_children = false;
+
return true;
no_memory:
- if (type)
- dom_string_unref(type);
+ dom_string_unref(type);
return false;
}
@@ -2712,6 +2746,7 @@ bool box_select(BOX_SPECIAL_PARAMS)
c2) == false) {
dom_node_unref(c2);
dom_node_unref(c);
+ form_free_control(gadget);
return false;
}
} else {
@@ -2722,6 +2757,7 @@ bool box_select(BOX_SPECIAL_PARAMS)
if (err != DOM_NO_ERR) {
dom_node_unref(c2);
dom_node_unref(c);
+ form_free_control(gadget);
return false;
}
@@ -2840,7 +2876,10 @@ bool box_select_add_option(struct form_control *control, dom_node *n)
if (value == NULL)
goto no_memory;
- dom_element_has_attribute(n, corestring_dom_selected, &selected);
+ if (dom_element_has_attribute(n, corestring_dom_selected, &selected) != DOM_NO_ERR) {
+ /* Assume not selected if we can't read the attribute presence */
+ selected = false;
+ }
/* replace spaces/TABs with hard spaces to prevent line wrapping */
text_nowrap = cnv_space2nbsp(text);
diff --git a/content/handlers/html/box_textarea.c b/content/handlers/html/box_textarea.c
index c19afbb..f0ba9f9 100644
--- a/content/handlers/html/box_textarea.c
+++ b/content/handlers/html/box_textarea.c
@@ -25,8 +25,11 @@
#include "utils/config.h"
#include "utils/log.h"
+#include "utils/messages.h"
#include "netsurf/keypress.h"
+#include "netsurf/misc.h"
#include "desktop/textarea.h"
+#include "desktop/gui_internal.h"
#include "html/html_internal.h"
#include "html/box.h"
@@ -41,6 +44,7 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t key)
struct textarea *ta = gadget->data.text.ta;
struct form* form = box->gadget->form;
struct content *c = (struct content *) html;
+ nserror res;
assert(ta != NULL);
@@ -48,9 +52,16 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t key)
switch (key) {
case NS_KEY_NL:
case NS_KEY_CR:
- if (form)
- form_submit(content_get_url(c), html->bw,
- form, 0);
+ if (form) {
+ res = form_submit(content_get_url(c),
+ html->bw,
+ form,
+ NULL);
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
+ }
return true;
case NS_KEY_TAB:
diff --git a/content/handlers/html/form.c b/content/handlers/html/form.c
index 4a9d710..2918ce7 100644
--- a/content/handlers/html/form.c
+++ b/content/handlers/html/form.c
@@ -223,6 +223,9 @@ void form_free_control(struct form_control *control)
free(control->name);
free(control->value);
free(control->initial_value);
+ if (control->last_synced_value != NULL) {
+ free(control->last_synced_value);
+ }
if (control->type == GADGET_SELECT) {
struct form_option *option, *next;
@@ -275,6 +278,10 @@ void form_free_control(struct form_control *control)
}
}
+ if (control->node_value != NULL) {
+ dom_string_unref(control->node_value);
+ }
+
free(control);
}
@@ -326,662 +333,1010 @@ bool form_add_option(struct form_control *control, char *value, char *text,
return true;
}
+/** string allocation size for numeric values in multipart data */
+#define FETCH_DATA_INT_VALUE_SIZE 20
-/* exported interface documented in html/form_internal.h */
-bool form_successful_controls_dom(struct form *_form,
- struct form_control *_submit_button,
- struct fetch_multipart_data **successful_controls)
+/**
+ * append split key name and integer value to a multipart data list
+ *
+ * \param name key name
+ * \param ksfx key name suffix
+ * \param value The value to encode
+ * \param fetch_data_next_ptr The multipart data list to append to.
+ */
+static nserror
+fetch_data_list_add_sname(const char *name,
+ const char *ksfx,
+ int value,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
{
- dom_html_form_element *form = _form->node;
- dom_html_element *submit_button = (_submit_button != NULL) ? _submit_button->node : NULL;
- dom_html_collection *form_elements = NULL;
- dom_html_options_collection *options = NULL;
- dom_node *form_element = NULL, *option_element = NULL;
- dom_exception err;
- dom_string *nodename = NULL, *inputname = NULL, *inputvalue = NULL, *inputtype = NULL;
- struct fetch_multipart_data sentinel, *last_success, *success_new;
- bool had_submit = false, element_disabled, checked;
- char *charset, *rawfile_temp = NULL, *basename;
- uint32_t index, element_count;
- struct image_input_coords *coords;
+ struct fetch_multipart_data *fetch_data;
+ int keysize;
- last_success = &sentinel;
- sentinel.next = NULL;
+ fetch_data = calloc(1, sizeof(*fetch_data));
+ if (fetch_data == NULL) {
+ NSLOG(netsurf, INFO, "failed allocation for fetch data");
+ return NSERROR_NOMEM;
+ }
- /** \todo Replace this call with something DOMish */
- charset = form_acceptable_charset(_form);
- if (charset == NULL) {
- NSLOG(netsurf, INFO, "failed to find charset");
- return false;
+ /* key name */
+ keysize = snprintf(fetch_data->name, 0, "%s%s", name, ksfx);
+ fetch_data->name = malloc(keysize + 1); /* allow for null */
+ if (fetch_data->name == NULL) {
+ free(fetch_data);
+ NSLOG(netsurf, INFO,
+ "keyname allocation failure for %s%s", name, ksfx);
+ return NSERROR_NOMEM;
+ }
+ snprintf(fetch_data->name, keysize + 1, "%s%s", name, ksfx);
+
+ /* value */
+ fetch_data->value = malloc(FETCH_DATA_INT_VALUE_SIZE);
+ if (fetch_data->value == NULL) {
+ free(fetch_data->name);
+ free(fetch_data);
+ NSLOG(netsurf, INFO, "value allocation failure");
+ return NSERROR_NOMEM;
}
+ snprintf(fetch_data->value, FETCH_DATA_INT_VALUE_SIZE, "%d", value);
-#define ENCODE_ITEM(i) (((i) == NULL) ? ( \
- form_encode_item("", 0, charset, _form->document_charset) \
- ):( \
- form_encode_item(dom_string_data(i), dom_string_byte_length(i), \
- charset, _form->document_charset) \
- ))
+ /* link into list */
+ **fetch_data_next_ptr = fetch_data;
+ *fetch_data_next_ptr = &fetch_data->next;
- err = dom_html_form_element_get_elements(form, &form_elements);
+ return NSERROR_OK;
+}
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO, "Could not get form elements");
- goto dom_no_memory;
- }
+/**
+ * append DOM string name/value pair to a multipart data list
+ *
+ * \param name key name
+ * \param value the value to associate with the key
+ * \param rawfile the raw file value to associate with the key.
+ * \param form_charset The form character set
+ * \param docu_charset The document character set for fallback
+ * \param fetch_data_next_ptr The multipart data list being constructed.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+fetch_data_list_add(dom_string *name,
+ dom_string *value,
+ const char *rawfile,
+ const char *form_charset,
+ const char *docu_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ struct fetch_multipart_data *fetch_data;
- err = dom_html_collection_get_length(form_elements, &element_count);
+ assert(name != NULL);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO, "Could not get form element count");
- goto dom_no_memory;
+ fetch_data = calloc(1, sizeof(*fetch_data));
+ if (fetch_data == NULL) {
+ NSLOG(netsurf, INFO, "failed allocation for fetch data");
+ return NSERROR_NOMEM;
}
- for (index = 0; index < element_count; index++) {
- if (form_element != NULL) {
- dom_node_unref(form_element);
- form_element = NULL;
- }
- if (nodename != NULL) {
- dom_string_unref(nodename);
- nodename = NULL;
- }
- if (inputname != NULL) {
- dom_string_unref(inputname);
- inputname = NULL;
- }
- if (inputvalue != NULL) {
- dom_string_unref(inputvalue);
- inputvalue = NULL;
- }
- if (inputtype != NULL) {
- dom_string_unref(inputtype);
- inputtype = NULL;
- }
- if (options != NULL) {
- dom_html_options_collection_unref(options);
- options = NULL;
- }
- err = dom_html_collection_item(form_elements,
- index, &form_element);
- if (err != DOM_NO_ERR) {
+ fetch_data->name = form_encode_item(dom_string_data(name),
+ dom_string_byte_length(name),
+ form_charset,
+ docu_charset);
+ if (fetch_data->name == NULL) {
+ NSLOG(netsurf, INFO, "Could not encode name for fetch data");
+ free(fetch_data);
+ return NSERROR_NOMEM;
+ }
+
+ if (value == NULL) {
+ fetch_data->value = strdup("");
+ } else {
+ fetch_data->value = form_encode_item(dom_string_data(value),
+ dom_string_byte_length(value),
+ form_charset,
+ docu_charset);
+ }
+ if (fetch_data->value == NULL) {
+ NSLOG(netsurf, INFO, "Could not encode value for fetch data");
+ free(fetch_data->name);
+ free(fetch_data);
+ return NSERROR_NOMEM;
+ }
+
+ /* deal with raw file name */
+ if (rawfile != NULL) {
+ fetch_data->file = true;
+ fetch_data->rawfile = strdup(rawfile);
+ if (fetch_data->rawfile == NULL) {
NSLOG(netsurf, INFO,
- "Could not retrieve form element %d", index);
- goto dom_no_memory;
+ "Could not encode rawfile value for fetch data");
+ free(fetch_data->value);
+ free(fetch_data->name);
+ free(fetch_data);
+ return NSERROR_NOMEM;
}
+ }
- /* Form elements are one of:
- * HTMLButtonElement
- * HTMLInputElement
- * HTMLTextAreaElement
- * HTMLSelectElement
- */
- err = dom_node_get_node_name(form_element, &nodename);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO, "Could not get node name");
- goto dom_no_memory;
- }
+ /* link into list */
+ **fetch_data_next_ptr = fetch_data;
+ *fetch_data_next_ptr = &fetch_data->next;
- if (dom_string_isequal(nodename, corestring_dom_TEXTAREA)) {
- err = dom_html_text_area_element_get_disabled(
- (dom_html_text_area_element *)form_element,
- &element_disabled);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get text area disabled property");
- goto dom_no_memory;
- }
- err = dom_html_text_area_element_get_name(
- (dom_html_text_area_element *)form_element,
- &inputname);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get text area name property");
- goto dom_no_memory;
- }
- } else if (dom_string_isequal(nodename, corestring_dom_SELECT)) {
- err = dom_html_select_element_get_disabled(
- (dom_html_select_element *)form_element,
- &element_disabled);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get select disabled property");
- goto dom_no_memory;
- }
- err = dom_html_select_element_get_name(
- (dom_html_select_element *)form_element,
- &inputname);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get select name property");
- goto dom_no_memory;
- }
- } else if (dom_string_isequal(nodename, corestring_dom_INPUT)) {
- err = dom_html_input_element_get_disabled(
- (dom_html_input_element *)form_element,
- &element_disabled);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input disabled property");
- goto dom_no_memory;
- }
- err = dom_html_input_element_get_name(
- (dom_html_input_element *)form_element,
- &inputname);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input name property");
- goto dom_no_memory;
- }
- } else if (dom_string_isequal(nodename, corestring_dom_BUTTON)) {
- err = dom_html_button_element_get_disabled(
- (dom_html_button_element *)form_element,
- &element_disabled);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get button disabled property");
- goto dom_no_memory;
- }
- err = dom_html_button_element_get_name(
- (dom_html_button_element *)form_element,
- &inputname);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get button name property");
- goto dom_no_memory;
- }
- } else {
- /* Unknown element type came through! */
- NSLOG(netsurf, INFO, "Unknown element type: %*s",
- (int)dom_string_byte_length(nodename),
- dom_string_data(nodename));
- goto dom_no_memory;
- }
- if (element_disabled)
- continue;
- if (inputname == NULL)
- continue;
+ return NSERROR_OK;
+}
- if (dom_string_isequal(nodename, corestring_dom_TEXTAREA)) {
- err = dom_html_text_area_element_get_value(
- (dom_html_text_area_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get text area content");
- goto dom_no_memory;
- }
- } else if (dom_string_isequal(nodename, corestring_dom_SELECT)) {
- uint32_t options_count, option_index;
- err = dom_html_select_element_get_options(
- (dom_html_select_element *)form_element,
- &options);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get select options collection");
- goto dom_no_memory;
- }
- err = dom_html_options_collection_get_length(
- options, &options_count);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get select options collection length");
- goto dom_no_memory;
- }
- for(option_index = 0; option_index < options_count;
- ++option_index) {
- bool selected;
- if (option_element != NULL) {
- dom_node_unref(option_element);
- option_element = NULL;
- }
- if (inputvalue != NULL) {
- dom_string_unref(inputvalue);
- inputvalue = NULL;
- }
- err = dom_html_options_collection_item(
- options, option_index, &option_element);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get options item %d",
- option_index);
- goto dom_no_memory;
- }
- err = dom_html_option_element_get_selected(
- (dom_html_option_element *)option_element,
- &selected);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get option selected property");
- goto dom_no_memory;
- }
- if (!selected)
- continue;
- err = dom_html_option_element_get_value(
- (dom_html_option_element *)option_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get option value");
- goto dom_no_memory;
- }
+/**
+ * process form HTMLTextAreaElement into multipart data.
+ *
+ * \param text_area_element The form select DOM element to convert.
+ * \param form_charset The form character set
+ * \param doc_charset The document character set for fallback
+ * \param fetch_data_next_ptr The multipart data list being constructed.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+form_dom_to_data_textarea(dom_html_text_area_element *text_area_element,
+ const char *form_charset,
+ const char *doc_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ dom_exception exp; /* the result from DOM operations */
+ bool element_disabled;
+ dom_string *inputname;
+ dom_string *inputvalue;
+ nserror res;
- success_new = calloc(1, sizeof(*success_new));
- if (success_new == NULL) {
- NSLOG(netsurf, INFO,
- "Could not allocate data for option");
- goto dom_no_memory;
- }
+ /* check if element is disabled */
+ exp = dom_html_text_area_element_get_disabled(text_area_element,
+ &element_disabled);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get text area disabled property. exp %d", exp);
+ return NSERROR_DOM;
+ }
- last_success->next = success_new;
- last_success = success_new;
+ if (element_disabled) {
+ /* allow enumeration to continue after disabled element */
+ return NSERROR_OK;
+ }
- success_new->name = ENCODE_ITEM(inputname);
- if (success_new->name == NULL) {
- NSLOG(netsurf, INFO,
- "Could not encode name for option");
- goto dom_no_memory;
- }
- success_new->value = ENCODE_ITEM(inputvalue);
- if (success_new->value == NULL) {
- NSLOG(netsurf, INFO,
- "Could not encode value for option");
- goto dom_no_memory;
- }
- }
- continue;
- } else if (dom_string_isequal(nodename, corestring_dom_BUTTON)) {
- err = dom_html_button_element_get_type(
- (dom_html_button_element *) form_element,
- &inputtype);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get button element type");
- goto dom_no_memory;
- }
- if (dom_string_caseless_isequal(
- inputtype, corestring_dom_submit)) {
-
- if (submit_button == NULL && !had_submit) {
- /* no button used, and first submit
- * node found, so use it
- */
- had_submit = true;
- } else if ((dom_node *)submit_button !=
- (dom_node *)form_element) {
- continue;
- }
+ /* obtain name property */
+ exp = dom_html_text_area_element_get_name(text_area_element,
+ &inputname);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get text area name property. exp %d", exp);
+ return NSERROR_DOM;
+ }
- err = dom_html_button_element_get_value(
- (dom_html_button_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get submit button value");
- goto dom_no_memory;
- }
- /* Drop through to report successful button */
- } else {
- continue;
- }
- } else if (dom_string_isequal(nodename, corestring_dom_INPUT)) {
- /* Things to consider here */
- /* Buttons -- only if the successful control */
- /* radio and checkbox -- only if selected */
- /* file -- also get the rawfile */
- /* everything else -- just value */
- err = dom_html_input_element_get_type(
- (dom_html_input_element *) form_element,
- &inputtype);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input element type");
- goto dom_no_memory;
- }
- if (dom_string_caseless_isequal(
- inputtype, corestring_dom_submit)) {
-
- if (submit_button == NULL && !had_submit) {
- /* no button used, and first submit
- * node found, so use it
- */
- had_submit = true;
- } else if ((dom_node *)submit_button !=
- (dom_node *)form_element) {
- continue;
- }
+ if (inputname == NULL) {
+ /* allow enumeration to continue after element with no name */
+ return NSERROR_OK;
+ }
- err = dom_html_input_element_get_value(
- (dom_html_input_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get submit button value");
- goto dom_no_memory;
- }
- /* Drop through to report the successful button */
- } else if (dom_string_caseless_isequal(
- inputtype, corestring_dom_image)) {
- /* We *ONLY* use an image input if it was the
- * thing which activated us
- */
- if ((dom_node *)submit_button !=
- (dom_node *)form_element)
- continue;
-
- err = dom_node_get_user_data(
- form_element,
- corestring_dom___ns_key_image_coords_node_data,
- &coords);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get image XY data");
- goto dom_no_memory;
- }
- if (coords == NULL) {
- NSLOG(netsurf, INFO,
- "No XY data on the image input");
- goto dom_no_memory;
- }
-
- basename = ENCODE_ITEM(inputname);
-
- success_new = calloc(1, sizeof(*success_new));
- if (success_new == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate data for image.x");
- goto dom_no_memory;
- }
-
- last_success->next = success_new;
- last_success = success_new;
-
- success_new->name = malloc(strlen(basename) + 3);
- if (success_new->name == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate name for image.x");
- goto dom_no_memory;
- }
- success_new->value = malloc(20);
- if (success_new->value == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate value for image.x");
- goto dom_no_memory;
- }
- sprintf(success_new->name, "%s.x", basename);
- sprintf(success_new->value, "%d", coords->x);
-
- success_new = calloc(1, sizeof(*success_new));
- if (success_new == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate data for image.y");
- goto dom_no_memory;
- }
-
- last_success->next = success_new;
- last_success = success_new;
-
- success_new->name = malloc(strlen(basename) + 3);
- if (success_new->name == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate name for image.y");
- goto dom_no_memory;
- }
- success_new->value = malloc(20);
- if (success_new->value == NULL) {
- free(basename);
- NSLOG(netsurf, INFO,
- "Could not allocate value for image.y");
- goto dom_no_memory;
- }
- sprintf(success_new->name, "%s.y", basename);
- sprintf(success_new->value, "%d", coords->y);
- free(basename);
- continue;
- } else if (dom_string_caseless_isequal(
- inputtype, corestring_dom_radio) ||
- dom_string_caseless_isequal(
- inputtype, corestring_dom_checkbox)) {
- err = dom_html_input_element_get_checked(
- (dom_html_input_element *)form_element,
- &checked);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input element checked");
- goto dom_no_memory;
- }
- if (!checked)
- continue;
- err = dom_html_input_element_get_value(
- (dom_html_input_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input element value");
- goto dom_no_memory;
- }
- if (inputvalue == NULL) {
- inputvalue = dom_string_ref(
- corestring_dom_on);
- }
- /* Fall through to simple allocation */
- } else if (dom_string_caseless_isequal(
- inputtype, corestring_dom_file)) {
-
- err = dom_html_input_element_get_value(
- (dom_html_input_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get file value");
- goto dom_no_memory;
- }
- err = dom_node_get_user_data(
- form_element,
- corestring_dom___ns_key_file_name_node_data,
- &rawfile_temp);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get file rawname");
- goto dom_no_memory;
- }
- rawfile_temp = strdup(rawfile_temp != NULL ?
- rawfile_temp :
- "");
- if (rawfile_temp == NULL) {
- NSLOG(netsurf, INFO,
- "Could not copy file rawname");
- goto dom_no_memory;
- }
- /* Fall out to the allocation */
- } else if (dom_string_caseless_isequal(
- inputtype, corestring_dom_reset) ||
- dom_string_caseless_isequal(
- inputtype, corestring_dom_button)) {
- /* Skip these */
- NSLOG(netsurf, INFO,
- "Skipping RESET and BUTTON");
- continue;
- } else {
- /* Everything else is treated as text values */
- err = dom_html_input_element_get_value(
- (dom_html_input_element *)form_element,
- &inputvalue);
- if (err != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
- "Could not get input value");
- goto dom_no_memory;
- }
- /* Fall out to the allocation */
- }
- }
+ /* obtain text area value */
+ exp = dom_html_text_area_element_get_value(text_area_element,
+ &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get text area content. exp %d", exp);
+ dom_string_unref(inputname);
+ return NSERROR_DOM;
+ }
- success_new = calloc(1, sizeof(*success_new));
- if (success_new == NULL) {
- NSLOG(netsurf, INFO,
- "Could not allocate data for generic");
- goto dom_no_memory;
- }
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ NULL,
+ form_charset,
+ doc_charset,
+ fetch_data_next_ptr);
- last_success->next = success_new;
- last_success = success_new;
+ dom_string_unref(inputvalue);
+ dom_string_unref(inputname);
- success_new->name = ENCODE_ITEM(inputname);
- if (success_new->name == NULL) {
- NSLOG(netsurf, INFO,
- "Could not encode name for generic");
- goto dom_no_memory;
- }
- success_new->value = ENCODE_ITEM(inputvalue);
- if (success_new->value == NULL) {
+ return res;
+}
+
+static nserror
+form_dom_to_data_select_option(dom_html_option_element *option_element,
+ dom_string *keyname,
+ const char *form_charset,
+ const char *docu_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res;
+ dom_exception exp; /* the result from DOM operations */
+ dom_string *value;
+ bool selected;
+
+ exp = dom_html_option_element_get_selected(option_element, &selected);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get option selected property");
+ return NSERROR_DOM;
+ }
+
+ if (!selected) {
+ /* unselected options do not add fetch data entries */
+ return NSERROR_OK;
+ }
+
+ exp = dom_html_option_element_get_value(option_element, &value);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get option value");
+ return NSERROR_DOM;
+ }
+
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(keyname,
+ value,
+ NULL,
+ form_charset,
+ docu_charset,
+ fetch_data_next_ptr);
+
+ dom_string_unref(value);
+
+ return res;
+}
+
+/**
+ * process form HTMLSelectElement into multipart data.
+ *
+ * \param select_element The form select DOM element to convert.
+ * \param form_charset The form character set
+ * \param doc_charset The document character set for fallback
+ * \param fetch_data_next_ptr The multipart data list being constructed.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+form_dom_to_data_select(dom_html_select_element *select_element,
+ const char *form_charset,
+ const char *doc_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res = NSERROR_OK;
+ dom_exception exp; /* the result from DOM operations */
+ bool element_disabled;
+ dom_string *inputname;
+ dom_html_options_collection *options = NULL;
+ uint32_t options_count;
+ uint32_t option_index;
+ dom_node *option_element = NULL;
+
+ /* check if element is disabled */
+ exp = dom_html_select_element_get_disabled(select_element,
+ &element_disabled);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get select disabled property. exp %d", exp);
+ return NSERROR_DOM;
+ }
+
+ if (element_disabled) {
+ /* allow enumeration to continue after disabled element */
+ return NSERROR_OK;
+ }
+
+ /* obtain name property */
+ exp = dom_html_select_element_get_name(select_element, &inputname);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get select name property. exp %d", exp);
+ return NSERROR_DOM;
+ }
+
+ if (inputname == NULL) {
+ /* allow enumeration to continue after element with no name */
+ return NSERROR_OK;
+ }
+
+ /* get options collection */
+ exp = dom_html_select_element_get_options(select_element, &options);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get select options collection");
+ dom_string_unref(inputname);
+ return NSERROR_DOM;
+ }
+
+ /* get options collection length */
+ exp = dom_html_options_collection_get_length(options, &options_count);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get select options collection length");
+ dom_html_options_collection_unref(options);
+ dom_string_unref(inputname);
+ return NSERROR_DOM;
+ }
+
+ /* iterate over options collection */
+ for (option_index = 0; option_index < options_count; ++option_index) {
+ exp = dom_html_options_collection_item(options,
+ option_index,
+ &option_element);
+ if (exp != DOM_NO_ERR) {
NSLOG(netsurf, INFO,
- "Could not encode value for generic");
- goto dom_no_memory;
+ "Could not get options item %d", option_index);
+ res = NSERROR_DOM;
+ } else {
+ res = form_dom_to_data_select_option(
+ (dom_html_option_element *)option_element,
+ inputname,
+ form_charset,
+ doc_charset,
+ fetch_data_next_ptr);
+
+ dom_node_unref(option_element);
}
- if (rawfile_temp != NULL) {
- success_new->file = true;
- success_new->rawfile = rawfile_temp;
- rawfile_temp = NULL;
+
+ if (res != NSERROR_OK) {
+ break;
}
}
- free(charset);
+ dom_html_options_collection_unref(options);
+ dom_string_unref(inputname);
+
+ return res;
+}
+
+static nserror
+form_dom_to_data_input_submit(dom_html_input_element *input_element,
+ dom_string *inputname,
+ const char *charset,
+ const char *document_charset,
+ dom_html_element **submit_button,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ dom_exception exp; /* the result from DOM operations */
+ dom_string *inputvalue;
+ nserror res;
- if (form_element != NULL) {
- dom_node_unref(form_element);
+ if (*submit_button == NULL) {
+ /* caller specified no button so use this one */
+ *submit_button = (dom_html_element *)input_element;
+ } else if (*submit_button != (dom_html_element *)input_element) {
+ return NSERROR_OK;
}
- if (form_elements != NULL) {
- dom_html_collection_unref(form_elements);
+ /* matched button used to submit form */
+ exp = dom_html_input_element_get_value(input_element, &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get submit button value");
+ return NSERROR_DOM;
}
- if (nodename != NULL) {
- dom_string_unref(nodename);
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ NULL,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ dom_string_unref(inputvalue);
+
+ return res;
+}
+
+
+
+static nserror
+form_dom_to_data_input_image(dom_html_input_element *input_element,
+ dom_string *inputname,
+ const char *charset,
+ const char *document_charset,
+ dom_html_element **submit_button,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res;
+ dom_exception exp; /* the result from DOM operations */
+ struct image_input_coords *coords;
+ char *basename;
+
+ /* Only use an image input if it was the thing which activated us */
+ if (*submit_button != (dom_html_element *)input_element) {
+ return NSERROR_OK;
+ }
+
+ exp = dom_node_get_user_data((dom_node *)input_element,
+ corestring_dom___ns_key_image_coords_node_data,
+ &coords);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get image XY data");
+ return NSERROR_DOM;
+ }
+
+ if (coords == NULL) {
+ NSLOG(netsurf, INFO, "No XY data on the image input");
+ return NSERROR_DOM;
+ }
+
+ /* encode input name once */
+ basename = form_encode_item(dom_string_data(inputname),
+ dom_string_byte_length(inputname),
+ charset,
+ document_charset);
+ if (basename == NULL) {
+ NSLOG(netsurf, INFO, "Could not encode basename");
+ return NSERROR_NOMEM;
+ }
+
+ res = fetch_data_list_add_sname(basename, ".x",
+ coords->x,
+ fetch_data_next_ptr);
+
+ if (res == NSERROR_OK) {
+ res = fetch_data_list_add_sname(basename, ".y",
+ coords->y,
+ fetch_data_next_ptr);
+ }
+
+ free(basename);
+
+ return res;
+}
+
+static nserror
+form_dom_to_data_input_checkbox(dom_html_input_element *input_element,
+ dom_string *inputname,
+ const char *charset,
+ const char *document_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res;
+ dom_exception exp; /* the result from DOM operations */
+ bool checked;
+ dom_string *inputvalue;
+
+ exp = dom_html_input_element_get_checked(input_element, &checked);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get input element checked");
+ return NSERROR_DOM;
+ }
+
+ if (!checked) {
+ /* unchecked items do not generate a data entry */
+ return NSERROR_OK;
+ }
+
+ exp = dom_html_input_element_get_value(input_element, &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get input element value");
+ return NSERROR_DOM;
+ }
+
+ /* ensure a default value */
+ if (inputvalue == NULL) {
+ inputvalue = dom_string_ref(corestring_dom_on);
+ }
+
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ NULL,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ dom_string_unref(inputvalue);
+
+ return res;
+}
+
+static nserror
+form_dom_to_data_input_file(dom_html_input_element *input_element,
+ dom_string *inputname,
+ const char *charset,
+ const char *document_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res;
+ dom_exception exp; /* the result from DOM operations */
+ dom_string *inputvalue;
+ const char *rawfile = NULL;
+
+ exp = dom_html_input_element_get_value(input_element, &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get file value");
+ return NSERROR_DOM;
+ }
+
+ exp = dom_node_get_user_data((dom_node *)input_element,
+ corestring_dom___ns_key_file_name_node_data,
+ &rawfile);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get file rawname");
+ return NSERROR_DOM;
+ }
+
+ if (rawfile == NULL) {
+ rawfile = "";
+ }
+
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ rawfile,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ dom_string_unref(inputvalue);
+
+ return res;
+}
+
+static nserror
+form_dom_to_data_input_text(dom_html_input_element *input_element,
+ dom_string *inputname,
+ const char *charset,
+ const char *document_charset,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ nserror res;
+ dom_exception exp; /* the result from DOM operations */
+ dom_string *inputvalue;
+
+ exp = dom_html_input_element_get_value(input_element, &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get input value");
+ return NSERROR_DOM;
+ }
+
+ /* add key/value pair to fetch data list */
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ NULL,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ dom_string_unref(inputvalue);
+
+ return res;
+}
+
+/**
+ * process form input element into multipart data.
+ *
+ * \param input_element The form input DOM element to convert.
+ * \param charset The form character set
+ * \param document_charset The document character set for fallback
+ * \param submit_button The DOM element of the button submitting the form
+ * \param had_submit A boolean value indicating if the submit button
+ * has already been processed in the form element enumeration.
+ * \param fetch_data_next_ptr The multipart data list being constructed.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+form_dom_to_data_input(dom_html_input_element *input_element,
+ const char *charset,
+ const char *document_charset,
+ dom_html_element **submit_button,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ dom_exception exp; /* the result from DOM operations */
+ bool element_disabled;
+ dom_string *inputname;
+ dom_string *inputtype;
+ nserror res;
+
+ /* check if element is disabled */
+ exp = dom_html_input_element_get_disabled(input_element,
+ &element_disabled);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get input disabled property. exp %d", exp);
+ return NSERROR_DOM;
+ }
+
+ if (element_disabled) {
+ /* disabled element requires no more processing */
+ return NSERROR_OK;
+ }
+
+ /* obtain name property */
+ exp = dom_html_input_element_get_name(input_element, &inputname);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get input name property. exp %d", exp);
+ return NSERROR_DOM;
}
- if (inputname != NULL) {
+ if (inputname == NULL) {
+ /* element with no name is not converted */
+ return NSERROR_OK;
+ }
+
+ /* get input type */
+ exp = dom_html_input_element_get_type(input_element, &inputtype);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get input element type");
dom_string_unref(inputname);
+ return NSERROR_DOM;
}
- if (inputvalue != NULL) {
- dom_string_unref(inputvalue);
+ /* process according to input element type */
+ if (dom_string_caseless_isequal(inputtype, corestring_dom_submit)) {
+
+ res = form_dom_to_data_input_submit(input_element,
+ inputname,
+ charset,
+ document_charset,
+ submit_button,
+ fetch_data_next_ptr);
+
+ } else if (dom_string_caseless_isequal(inputtype,
+ corestring_dom_image)) {
+
+ res = form_dom_to_data_input_image(input_element,
+ inputname,
+ charset,
+ document_charset,
+ submit_button,
+ fetch_data_next_ptr);
+
+ } else if (dom_string_caseless_isequal(inputtype,
+ corestring_dom_radio) ||
+ dom_string_caseless_isequal(inputtype,
+ corestring_dom_checkbox)) {
+
+ res = form_dom_to_data_input_checkbox(input_element,
+ inputname,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ } else if (dom_string_caseless_isequal(inputtype,
+ corestring_dom_file)) {
+
+ res = form_dom_to_data_input_file(input_element,
+ inputname,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
+ } else if (dom_string_caseless_isequal(inputtype,
+ corestring_dom_reset) ||
+ dom_string_caseless_isequal(inputtype,
+ corestring_dom_button)) {
+ /* Skip these */
+ NSLOG(netsurf, INFO, "Skipping RESET and BUTTON");
+ res = NSERROR_OK;
+
+ } else {
+ /* Everything else is treated as text values */
+ res = form_dom_to_data_input_text(input_element,
+ inputname,
+ charset,
+ document_charset,
+ fetch_data_next_ptr);
+
}
- if (options != NULL) {
- dom_html_options_collection_unref(options);
+ dom_string_unref(inputtype);
+ dom_string_unref(inputname);
+
+ return res;
+}
+
+/**
+ * process form HTMLButtonElement into multipart data.
+ *
+ * https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element
+ *
+ * \param button_element The form button DOM element to convert.
+ * \param form_charset The form character set
+ * \param doc_charset The document character set for fallback
+ * \param submit_button The DOM element of the button submitting the form
+ * \param fetch_data_next_ptr The multipart data list being constructed.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+form_dom_to_data_button(dom_html_button_element *button_element,
+ const char *form_charset,
+ const char *doc_charset,
+ dom_html_element **submit_button,
+ struct fetch_multipart_data ***fetch_data_next_ptr)
+{
+ dom_exception exp; /* the result from DOM operations */
+ bool element_disabled;
+ dom_string *inputname;
+ dom_string *inputvalue;
+ dom_string *inputtype;
+ nserror res = NSERROR_OK;
+
+ /* check if element is disabled */
+ exp = dom_html_button_element_get_disabled(button_element,
+ &element_disabled);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Unable to get disabled property. exp %d", exp);
+ return NSERROR_DOM;
}
- if (option_element != NULL) {
- dom_node_unref(option_element);
+ if (element_disabled) {
+ /* allow enumeration to continue after disabled element */
+ return NSERROR_OK;
}
- if (inputtype != NULL) {
+ /* get the type attribute */
+ exp = dom_html_button_element_get_type(button_element, &inputtype);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get button element type");
+ return NSERROR_DOM;
+ }
+
+ /* If the type attribute is "reset" or "button" the element is
+ * barred from constraint validation. Specification says
+ * default and invalid values result in submit which will
+ * be considered.
+ */
+ if (dom_string_caseless_isequal(inputtype, corestring_dom_reset)) {
+ /* multipart data entry not required for reset type */
dom_string_unref(inputtype);
+ return NSERROR_OK;
}
+ if (dom_string_caseless_isequal(inputtype, corestring_dom_button)) {
+ /* multipart data entry not required for button type */
+ dom_string_unref(inputtype);
+ return NSERROR_OK;
+ }
+ dom_string_unref(inputtype);
- if (rawfile_temp != NULL) {
- free(rawfile_temp);
+ /* only submision button generates an element */
+ if (*submit_button == NULL) {
+ /* no submission button selected yet so use this one */
+ *submit_button = (dom_html_element *)button_element;
+ }
+ if (*submit_button != (dom_html_element *)button_element) {
+ return NSERROR_OK;
}
- *successful_controls = sentinel.next;
+ /* obtain name property */
+ exp = dom_html_button_element_get_name(button_element, &inputname);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "Could not get button name property. exp %d", exp);
+ return NSERROR_DOM;
+ }
- return true;
+ if (inputname == NULL) {
+ /* allow enumeration to continue after element with no name */
+ return NSERROR_OK;
+ }
-dom_no_memory:
- free(charset);
- fetch_multipart_data_destroy(sentinel.next);
+ /* get button value and add to fetch data list */
+ exp = dom_html_button_element_get_value(button_element, &inputvalue);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get submit button value");
+ res = NSERROR_DOM;
+ } else {
+ res = fetch_data_list_add(inputname,
+ inputvalue,
+ NULL,
+ form_charset,
+ doc_charset,
+ fetch_data_next_ptr);
- if (form_elements != NULL)
- dom_html_collection_unref(form_elements);
- if (form_element != NULL)
- dom_node_unref(form_element);
- if (nodename != NULL)
- dom_string_unref(nodename);
- if (inputname != NULL)
- dom_string_unref(inputname);
- if (inputvalue != NULL)
dom_string_unref(inputvalue);
- if (options != NULL)
- dom_html_options_collection_unref(options);
- if (option_element != NULL)
- dom_node_unref(option_element);
- if (inputtype != NULL)
- dom_string_unref(inputtype);
- if (rawfile_temp != NULL)
- free(rawfile_temp);
+ }
- return false;
+ dom_string_unref(inputname);
+
+ return res;
}
-#undef ENCODE_ITEM
+
/**
- * Encode controls using application/x-www-form-urlencoded.
+ * Construct multipart data list from 'successful' controls via the DOM.
+ *
+ * All text strings in the successful controls list will be in the charset most
+ * appropriate for submission. Therefore, no utf8_to_* processing should be
+ * performed upon them.
+ *
+ * \todo The chosen charset needs to be made available such that it can be
+ * included in the submission request (e.g. in the fetch's Content-Type header)
+ *
+ * See HTML 4.01 section 17.13.2.
+ *
+ * \note care is taken to abort even if the error is recoverable as it
+ * is not desirable to submit incomplete form data.
*
- * \param form form to which successful controls relate
- * \param control linked list of fetch_multipart_data
- * \param query_string iff true add '?' to the start of returned data
- * \return URL-encoded form, or 0 on memory exhaustion
+ * \param[in] form form to search for successful controls
+ * \param[in] submit_button control used to submit the form, if any
+ * \param[out] fetch_data_out updated to point to linked list of
+ * fetch_multipart_data, NULL if no controls
+ * \return NSERROR_OK on success or appropriate error code
*/
+static nserror
+form_dom_to_data(struct form *form,
+ struct form_control *submit_control,
+ struct fetch_multipart_data **fetch_data_out)
+{
+ nserror res = NSERROR_OK;
+ char *charset; /* form characterset */
+ dom_exception exp; /* the result from DOM operations */
+ dom_html_collection *elements = NULL; /* the dom form elements */
+ uint32_t element_count; /* the number of elements in the DOM form */
+ uint32_t element_idx; /* the index of thr enumerated element */
+ dom_node *element = NULL; /* the DOM form element */
+ dom_string *nodename = NULL; /* the DOM node name of the element */
+ struct fetch_multipart_data *fetch_data = NULL; /* fetch data list */
+ struct fetch_multipart_data **fetch_data_next = &fetch_data;
+ dom_html_element *submit_button;
+
+ /* obtain the submit_button DOM node from the control */
+ if (submit_control != NULL) {
+ submit_button = submit_control->node;
+ } else {
+ submit_button = NULL;
+ }
+
+ /** \todo Replace this call with something DOMish */
+ charset = form_acceptable_charset(form);
+ if (charset == NULL) {
+ NSLOG(netsurf, INFO, "failed to find charset");
+ return NSERROR_NOMEM;
+ }
+
+ /* obtain the form elements and count */
+ exp = dom_html_form_element_get_elements(form->node, &elements);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get form elements");
+ free(charset);
+ return NSERROR_DOM;
+ }
+
+ exp = dom_html_collection_get_length(elements, &element_count);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO, "Could not get form element count");
+ res = NSERROR_DOM;
+ goto form_dom_to_data_error;
+ }
+
+ for (element_idx = 0; element_idx < element_count; element_idx++) {
+ /* obtain a form element */
+ exp = dom_html_collection_item(elements, element_idx, &element);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "retrieving form element %d failed with %d",
+ element_idx, exp);
+ res = NSERROR_DOM;
+ goto form_dom_to_data_error;
+ }
+
+ /* node name from element */
+ exp = dom_node_get_node_name(element, &nodename);
+ if (exp != DOM_NO_ERR) {
+ NSLOG(netsurf, INFO,
+ "getting element node name %d failed with %d",
+ element_idx, exp);
+ dom_node_unref(element);
+ res = NSERROR_DOM;
+ goto form_dom_to_data_error;
+ }
+
+ if (dom_string_isequal(nodename, corestring_dom_TEXTAREA)) {
+ /* Form element is HTMLTextAreaElement */
+ res = form_dom_to_data_textarea(
+ (dom_html_text_area_element *)element,
+ charset,
+ form->document_charset,
+ &fetch_data_next);
+
+ } else if (dom_string_isequal(nodename, corestring_dom_SELECT)) {
+ /* Form element is HTMLSelectElement */
+ res = form_dom_to_data_select(
+ (dom_html_select_element *)element,
+ charset,
+ form->document_charset,
+ &fetch_data_next);
+
+ } else if (dom_string_isequal(nodename, corestring_dom_INPUT)) {
+ /* Form element is HTMLInputElement */
+ res = form_dom_to_data_input(
+ (dom_html_input_element *)element,
+ charset,
+ form->document_charset,
+ &submit_button,
+ &fetch_data_next);
+
+ } else if (dom_string_isequal(nodename, corestring_dom_BUTTON)) {
+ /* Form element is HTMLButtonElement */
+ res = form_dom_to_data_button(
+ (dom_html_button_element *)element,
+ charset,
+ form->document_charset,
+ &submit_button,
+ &fetch_data_next);
+
+ } else {
+ /* Form element is not handled */
+ NSLOG(netsurf, INFO,
+ "Unhandled element type: %*s",
+ (int)dom_string_byte_length(nodename),
+ dom_string_data(nodename));
+ res = NSERROR_DOM;
+
+ }
+
+ dom_string_unref(nodename);
+ dom_node_unref(element);
+
+ /* abort form element enumeration on error */
+ if (res != NSERROR_OK) {
+ goto form_dom_to_data_error;
+ }
+ }
+
+ *fetch_data_out = fetch_data;
+ dom_html_collection_unref(elements);
+ free(charset);
+
+ return NSERROR_OK;
+
+form_dom_to_data_error:
+ fetch_multipart_data_destroy(fetch_data);
+ dom_html_collection_unref(elements);
+ free(charset);
-static char *form_url_encode(struct form *form,
+ return res;
+}
+
+/**
+ * Encode controls using application/x-www-form-urlencoded.
+ *
+ * \param[in] form form to which successful controls relate
+ * \param[in] control linked list of fetch_multipart_data
+ * \param[out] encoded_out URL-encoded form data
+ * \return NSERROR_OK on success and \a encoded_out updated else appropriate error code
+ */
+static nserror
+form_url_encode(struct form *form,
struct fetch_multipart_data *control,
- bool query_string)
+ char **encoded_out)
{
char *name, *value;
char *s, *s2;
unsigned int len, len1, len_init;
- nserror url_err;
-
- if (query_string)
- s = malloc(2);
- else
- s = malloc(1);
+ nserror res;
- if (s == NULL)
- return NULL;
+ s = malloc(1);
- if (query_string) {
- s[0] = '?';
- s[1] = '\0';
- len_init = len = 1;
- } else {
- s[0] = '\0';
- len_init = len = 0;
+ if (s == NULL) {
+ return NSERROR_NOMEM;
}
+ s[0] = '\0';
+ len_init = len = 0;
+
for (; control; control = control->next) {
- url_err = url_escape(control->name, true, NULL, &name);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->name, true, NULL, &name);
+ if (res != NSERROR_OK) {
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
- url_err = url_escape(control->value, true, NULL, &value);
- if (url_err == NSERROR_NOMEM) {
+ res = url_escape(control->value, true, NULL, &value);
+ if (res != NSERROR_OK) {
free(name);
free(s);
- return NULL;
+ return res;
}
- assert(url_err == NSERROR_OK);
-
/* resize string to allow for new key/value pair,
* equals, amphersand and terminator
*/
len1 = len + strlen(name) + strlen(value) + 2;
s2 = realloc(s, len1 + 1);
- if (!s2) {
+ if (s2 == NULL) {
free(value);
free(name);
free(s);
- return NULL;
+ return NSERROR_NOMEM;
}
s = s2;
@@ -995,7 +1350,10 @@ static char *form_url_encode(struct form *form,
/* Replace trailing '&' */
s[len - 1] = '\0';
}
- return s;
+
+ *encoded_out = s;
+
+ return NSERROR_OK;
}
/**
@@ -1008,17 +1366,15 @@ char *form_acceptable_charset(struct form *form)
{
char *temp, *c;
- if (!form)
- return NULL;
-
if (!form->accept_charsets) {
/* no accept-charsets attribute for this form */
- if (form->document_charset)
+ if (form->document_charset) {
/* document charset present, so use it */
return strdup(form->document_charset);
- else
+ } else {
/* no document charset, so default to 8859-1 */
return strdup("ISO-8859-1");
+ }
}
/* make temporary copy of accept-charsets attribute */
@@ -1074,8 +1430,11 @@ char *form_acceptable_charset(struct form *form)
* used iff converting to charset fails
* \return Pointer to converted string (on heap, caller frees), or NULL
*/
-char *form_encode_item(const char *item, uint32_t len, const char *charset,
- const char *fallback)
+char *
+form_encode_item(const char *item,
+ uint32_t len,
+ const char *charset,
+ const char *fallback)
{
nserror err;
char *ret = NULL;
@@ -1768,98 +2127,85 @@ void form_radio_set(struct form_control *radio)
}
-/**
- * Collect controls and submit a form.
- */
-
-void form_submit(nsurl *page_url, struct browser_window *target,
- struct form *form, struct form_control *submit_button)
+/* private interface described in html/form_internal.h */
+nserror
+form_submit(nsurl *page_url,
+ struct browser_window *target,
+ struct form *form,
+ struct form_control *submit_button)
{
- char *data = NULL;
- struct fetch_multipart_data *success;
+ nserror res;
+ char *data = NULL; /* encoded form data */
+ struct fetch_multipart_data *success = NULL; /* gcc is incapable of correctly reasoning about use and generates "maybe used uninitialised" warnings */
nsurl *action_url;
- nsurl *action_query;
- nserror error;
+ nsurl *query_url;
assert(form != NULL);
- if (form_successful_controls_dom(form, submit_button, &success) == false) {
- guit->misc->warning("NoMemory", 0);
- return;
+ /* obtain list of controls from DOM */
+ res = form_dom_to_data(form, submit_button, &success);
+ if (res != NSERROR_OK) {
+ return res;
}
/* Decompose action */
- if (nsurl_create(form->action, &action_url) != NSERROR_OK) {
- free(data);
+ res = nsurl_create(form->action, &action_url);
+ if (res != NSERROR_OK) {
fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
+ return res;
}
switch (form->method) {
case method_GET:
- data = form_url_encode(form, success, true);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- return;
- }
-
- /* Replace query segment */
- error = nsurl_replace_query(action_url, data, &action_query);
- if (error != NSERROR_OK) {
- nsurl_unref(action_query);
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ /* Replace query segment */
+ res = nsurl_replace_query(action_url, data, &query_url);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ query_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+
+ nsurl_unref(query_url);
+ }
free(data);
- fetch_multipart_data_destroy(success);
- guit->misc->warning(messages_get_errorcode(error), 0);
- return;
}
-
- /* Construct submit url */
- browser_window_navigate(target,
- action_query,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
-
- nsurl_unref(action_query);
break;
case method_POST_URLENC:
- data = form_url_encode(form, success, false);
- if (data == NULL) {
- fetch_multipart_data_destroy(success);
- guit->misc->warning("NoMemory", 0);
- nsurl_unref(action_url);
- return;
+ res = form_url_encode(form, success, &data);
+ if (res == NSERROR_OK) {
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ data,
+ NULL,
+ NULL);
+ free(data);
}
-
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- data,
- NULL,
- NULL);
break;
case method_POST_MULTIPART:
- browser_window_navigate(target,
- action_url,
- page_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- success,
- NULL);
+ res = browser_window_navigate(target,
+ action_url,
+ page_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ success,
+ NULL);
break;
}
nsurl_unref(action_url);
fetch_multipart_data_destroy(success);
- free(data);
+
+ return res;
}
void form_gadget_update_value(struct form_control *control, char *value)
@@ -1896,4 +2242,112 @@ void form_gadget_update_value(struct form_control *control, char *value)
/* Do nothing */
break;
}
+
+ /* Finally, sync this with the DOM */
+ form_gadget_sync_with_dom(control);
+}
+
+/* Exported API, see form_internal.h */
+void
+form_gadget_sync_with_dom(struct form_control *control)
+{
+ dom_exception exc;
+ dom_string *value = NULL;
+ bool changed_dom = false;
+
+ if (control->syncing ||
+ (control->type != GADGET_TEXTBOX &&
+ control->type != GADGET_PASSWORD &&
+ control->type != GADGET_HIDDEN &&
+ control->type != GADGET_TEXTAREA)) {
+ /* Not a control we support, or the control is already
+ * mid-sync so we don't want to disrupt that
+ */
+ return;
+ }
+
+ control->syncing = true;
+
+ /* If we've changed value, sync that toward the DOM */
+ if ((control->last_synced_value == NULL &&
+ control->value != NULL &&
+ control->value[0] != '\0') ||
+ (control->last_synced_value != NULL &&
+ control->value != NULL &&
+ strcmp(control->value, control->last_synced_value) != 0)) {
+ char *dup = strdup(control->value);
+ if (dup == NULL) {
+ goto out;
+ }
+ if (control->last_synced_value != NULL) {
+ free(control->last_synced_value);
+ }
+ control->last_synced_value = dup;
+ exc = dom_string_create((uint8_t *)(control->value),
+ strlen(control->value), &value);
+ if (exc != DOM_NO_ERR) {
+ goto out;
+ }
+ if (control->node_value != NULL) {
+ dom_string_unref(control->node_value);
+ }
+ control->node_value = value;
+ value = NULL;
+ if (control->type == GADGET_TEXTAREA) {
+ exc = dom_html_text_area_element_set_value(control->node, control->node_value);
+ } else {
+ exc = dom_html_input_element_set_value(control->node, control->node_value);
+ }
+ if (exc != DOM_NO_ERR) {
+ goto out;
+ }
+ changed_dom = true;
+ }
+
+ /* Now check if the DOM has changed since our last go */
+ if (control->type == GADGET_TEXTAREA) {
+ exc = dom_html_text_area_element_get_value(control->node, &value);
+ } else {
+ exc = dom_html_input_element_get_value(control->node, &value);
+ }
+
+ if (exc != DOM_NO_ERR) {
+ /* Nothing much we can do here */
+ goto out;
+ }
+
+ if (!dom_string_isequal(control->node_value, value)) {
+ /* The DOM has changed */
+ if (!changed_dom) {
+ /* And it wasn't us */
+ char *value_s = strndup(
+ dom_string_data(value),
+ dom_string_byte_length(value));
+ char *dup = NULL;
+ if (value_s == NULL) {
+ goto out;
+ }
+ dup = strdup(value_s);
+ if (dup == NULL) {
+ free(value_s);
+ goto out;
+ }
+ free(control->value);
+ control->value = value_s;
+ free(control->last_synced_value);
+ control->last_synced_value = dup;
+ if (control->type != GADGET_HIDDEN &&
+ control->data.text.ta != NULL) {
+ textarea_set_text(control->data.text.ta,
+ value_s);
+ }
+ }
+ control->node_value = value;
+ value = NULL;
+ }
+
+out:
+ if (value != NULL)
+ dom_string_unref(value);
+ control->syncing = false;
}
diff --git a/content/handlers/html/form_internal.h b/content/handlers/html/form_internal.h
index a77e823..6575224 100644
--- a/content/handlers/html/form_internal.h
+++ b/content/handlers/html/form_internal.h
@@ -72,6 +72,8 @@ struct image_input_coords {
/** Form control. */
struct form_control {
void *node; /**< Corresponding DOM node */
+ struct dom_string *node_value; /**< The last value sync'd with the DOM */
+ bool syncing; /**< Set if a DOM sync is in-progress */
struct html_content *html; /**< HTML content containing control */
form_control_type type; /**< Type of control */
@@ -81,6 +83,7 @@ struct form_control {
char *name; /**< Control name */
char *value; /**< Current value of control */
char *initial_value; /**< Initial value of control */
+ char *last_synced_value; /**< The last value sync'd to the DOM */
bool disabled; /**< Whether control is disabled */
struct box *box; /**< Box for control */
@@ -195,29 +198,6 @@ bool form_successful_controls(struct form *form,
struct fetch_multipart_data **successful_controls);
/**
- * Identify 'successful' controls via the DOM.
- *
- * All text strings in the successful controls list will be in the charset most
- * appropriate for submission. Therefore, no utf8_to_* processing should be
- * performed upon them.
- *
- * \todo The chosen charset needs to be made available such that it can be
- * included in the submission request (e.g. in the fetch's Content-Type header)
- *
- * See HTML 4.01 section 17.13.2.
- *
- * \param[in] form form to search for successful controls
- * \param[in] submit_button control used to submit the form, if any
- * \param[out] successful_controls updated to point to linked list of
- * fetch_multipart_data, 0 if no controls
- * \return true on success, false on memory exhaustion
- */
-bool form_successful_controls_dom(struct form *form,
- struct form_control *submit_button,
- struct fetch_multipart_data **successful_controls);
-
-
-/**
* Open a select menu for a select form control, creating it if necessary.
*
* \param client_data data passed to the redraw callback
@@ -268,10 +248,34 @@ void form_select_mouse_drag_end(struct form_control *control,
enum browser_mouse_state mouse, int x, int y);
void form_select_get_dimensions(struct form_control *control,
int *width, int *height);
-void form_submit(struct nsurl *page_url, struct browser_window *target,
+
+/**
+ * navigate browser window based on form submission.
+ *
+ * \param page_url content url
+ * \param target The browsing context in which the navigation will occour.
+ * \param form The form to submit.
+ * \param submit_button The control used to submit the form.
+ */
+nserror form_submit(struct nsurl *page_url, struct browser_window *target,
struct form *form, struct form_control *submit_button);
+
void form_radio_set(struct form_control *radio);
void form_gadget_update_value(struct form_control *control, char *value);
+/**
+ * Synchronise this gadget with its associated DOM node.
+ *
+ * If the DOM has changed and the gadget has not, the DOM's new value is
+ * imported into the gadget. If the gadget's value has changed and the DOM's
+ * has not, the gadget's value is pushed into the DOM.
+ * If both have changed, the gadget's value wins.
+ *
+ * \param control The form gadget to synchronise
+ *
+ * \note Currently this will only synchronise input gadgets (text/password)
+ */
+void form_gadget_sync_with_dom(struct form_control *control);
+
#endif
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 62f625f..33dcf2a 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -115,14 +115,16 @@ static void html_box_convert_done(html_content *c, bool success)
NSLOG(netsurf, INFO, "Done XML to box (%p)", c);
+ c->box_conversion_context = NULL;
+
/* Clean up and report error if unsuccessful or aborted */
if ((success == false) || (c->aborted)) {
html_object_free_objects(c);
if (success == false) {
- content_broadcast_errorcode(&c->base, NSERROR_BOX_CONVERT);
+ content_broadcast_error(&c->base, NSERROR_BOX_CONVERT, NULL);
} else {
- content_broadcast_errorcode(&c->base, NSERROR_STOPPED);
+ content_broadcast_error(&c->base, NSERROR_STOPPED, NULL);
}
content_set_error(&c->base);
@@ -144,7 +146,7 @@ static void html_box_convert_done(html_content *c, bool success)
* like the other error paths
*/
NSLOG(netsurf, INFO, "error retrieving html element from dom");
- content_broadcast_errorcode(&c->base, NSERROR_DOM);
+ content_broadcast_error(&c->base, NSERROR_DOM, NULL);
content_set_error(&c->base);
return;
}
@@ -154,7 +156,7 @@ static void html_box_convert_done(html_content *c, bool success)
if (err != NSERROR_OK) {
NSLOG(netsurf, INFO, "imagemap extraction failed");
html_object_free_objects(c);
- content_broadcast_errorcode(&c->base, err);
+ content_broadcast_error(&c->base, err, NULL);
content_set_error(&c->base);
dom_node_unref(html);
return;
@@ -570,6 +572,28 @@ static bool html_process_img(html_content *c, dom_node *node)
return success;
}
+static void html_get_dimensions(html_content *htmlc)
+{
+ unsigned w;
+ unsigned h;
+ union content_msg_data msg_data = {
+ .getdims = {
+ .viewport_width = &w,
+ .viewport_height = &h,
+ },
+ };
+
+ content_broadcast(&htmlc->base, CONTENT_MSG_GETDIMS, &msg_data);
+
+ htmlc->media.width = nscss_pixels_physical_to_css(INTTOFIX(w));
+ htmlc->media.height = nscss_pixels_physical_to_css(INTTOFIX(h));
+ htmlc->media.client_font_size =
+ FDIV(INTTOFIX(nsoption_int(font_size)), F_10);
+ htmlc->media.client_line_height =
+ FMUL(nscss_len2px(NULL, htmlc->media.client_font_size,
+ CSS_UNIT_PT, NULL), FLTTOFIX(1.33));
+}
+
/* exported function documented in html/html_internal.h */
void html_finish_conversion(html_content *htmlc)
{
@@ -580,7 +604,7 @@ void html_finish_conversion(html_content *htmlc)
/* Bail out if we've been aborted */
if (htmlc->aborted) {
- content_broadcast_errorcode(&htmlc->base, NSERROR_STOPPED);
+ content_broadcast_error(&htmlc->base, NSERROR_STOPPED, NULL);
content_set_error(&htmlc->base);
return;
}
@@ -604,7 +628,7 @@ void html_finish_conversion(html_content *htmlc)
/* create new css selection context */
error = html_css_new_selection_context(htmlc, &htmlc->select_ctx);
if (error != NSERROR_OK) {
- content_broadcast_errorcode(&htmlc->base, error);
+ content_broadcast_error(&htmlc->base, error, NULL);
content_set_error(&htmlc->base);
return;
}
@@ -627,17 +651,19 @@ void html_finish_conversion(html_content *htmlc)
exc = dom_document_get_document_element(htmlc->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
NSLOG(netsurf, INFO, "error retrieving html element from dom");
- content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
+ content_broadcast_error(&htmlc->base, NSERROR_DOM, NULL);
content_set_error(&htmlc->base);
return;
}
- error = dom_to_box(html, htmlc, html_box_convert_done);
+ html_get_dimensions(htmlc);
+
+ error = dom_to_box(html, htmlc, html_box_convert_done, &htmlc->box_conversion_context);
if (error != NSERROR_OK) {
NSLOG(netsurf, INFO, "box conversion failed");
dom_node_unref(html);
html_object_free_objects(htmlc);
- content_broadcast_errorcode(&htmlc->base, error);
+ content_broadcast_error(&htmlc->base, error, NULL);
content_set_error(&htmlc->base);
return;
}
@@ -645,6 +671,56 @@ void html_finish_conversion(html_content *htmlc)
dom_node_unref(html);
}
+/* handler for a SCRIPT which has been added to a tree */
+static void
+dom_SCRIPT_showed_up(html_content *htmlc, dom_html_script_element *script)
+{
+ dom_exception exc;
+ dom_html_script_element_flags flags;
+ dom_hubbub_error res;
+ bool within;
+
+ if (!htmlc->enable_scripting) {
+ NSLOG(netsurf, INFO, "Encountered a script, but scripting is off, ignoring");
+ return;
+ }
+
+ NSLOG(netsurf, DEEPDEBUG, "Encountered a script, node %p showed up", script);
+
+ exc = dom_html_script_element_get_flags(script, &flags);
+ if (exc != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to retrieve flags, giving up");
+ return;
+ }
+
+ if (flags & DOM_HTML_SCRIPT_ELEMENT_FLAG_PARSER_INSERTED) {
+ NSLOG(netsurf, DEBUG, "Script was parser inserted, skipping");
+ return;
+ }
+
+ exc = dom_node_contains(htmlc->document, script, &within);
+ if (exc != DOM_NO_ERR) {
+ NSLOG(netsurf, DEBUG, "Unable to determine if script was within document, ignoring");
+ return;
+ }
+
+ if (!within) {
+ NSLOG(netsurf, DEBUG, "Script was not within the document, ignoring for now");
+ return;
+ }
+
+ res = html_process_script(htmlc, (dom_node *) script);
+ if (res == DOM_HUBBUB_OK) {
+ NSLOG(netsurf, DEEPDEBUG, "Inserted script has finished running");
+ } else {
+ if (res == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED)) {
+ NSLOG(netsurf, DEEPDEBUG, "Inserted script has launced asynchronously");
+ } else {
+ NSLOG(netsurf, DEEPDEBUG, "Failure starting script");
+ }
+ }
+}
+
/* callback for DOMNodeInserted end type */
static void
dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
@@ -693,6 +769,9 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
case DOM_HTML_ELEMENT_TYPE_STYLE:
html_css_process_style(htmlc, (dom_node *) node);
break;
+ case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+ dom_SCRIPT_showed_up(htmlc, (dom_html_script_element *) node);
+ break;
default:
break;
}
@@ -720,7 +799,56 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
}
}
-/* callback for DOMNodeInserted end type */
+/* callback for DOMNodeInsertedIntoDocument end type */
+static void
+dom_default_action_DOMNodeInsertedIntoDocument_cb(struct dom_event *evt, void *pw)
+{
+ html_content *htmlc = pw;
+ dom_event_target *node;
+ dom_node_type type;
+ dom_exception exc;
+
+ exc = dom_event_get_target(evt, &node);
+ if ((exc == DOM_NO_ERR) && (node != NULL)) {
+ exc = dom_node_get_node_type(node, &type);
+ if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
+ /* an element node has been modified */
+ dom_html_element_type tag_type;
+
+ exc = dom_html_element_get_tag_type(node, &tag_type);
+ if (exc != DOM_NO_ERR) {
+ tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
+ }
+
+ switch (tag_type) {
+ case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+ dom_SCRIPT_showed_up(htmlc, (dom_html_script_element *) node);
+ default:
+ break;
+ }
+ }
+ dom_node_unref(node);
+ }
+}
+
+/* Deal with input elements being modified by resyncing their gadget
+ * if they have one.
+ */
+static void html_texty_element_update(html_content *htmlc, dom_node *node)
+{
+ struct box *box = box_for_node(node);
+ if (box == NULL) {
+ return; /* No Box (yet?) so no gadget to update */
+ }
+ if (box->gadget == NULL) {
+ return; /* No gadget yet (under construction perhaps?) */
+ }
+ form_gadget_sync_with_dom(box->gadget);
+ /* And schedule a redraw for the box */
+ html__redraw_a_box(htmlc, box);
+}
+
+/* callback for DOMSubtreeModified end type */
static void
dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
{
@@ -752,6 +880,9 @@ dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
case DOM_HTML_ELEMENT_TYPE_STYLE:
html_css_update_style(htmlc, (dom_node *)node);
break;
+ case DOM_HTML_ELEMENT_TYPE_TEXTAREA:
+ case DOM_HTML_ELEMENT_TYPE_INPUT:
+ html_texty_element_update(htmlc, (dom_node *)node);
default:
break;
}
@@ -787,11 +918,13 @@ dom_event_fetcher(dom_string *type,
dom_default_action_phase phase,
void **pw)
{
- NSLOG(netsurf, DEEPDEBUG, "type:%s", dom_string_data(type));
+ NSLOG(netsurf, DEEPDEBUG, "phase:%d type:%s", phase, dom_string_data(type));
if (phase == DOM_DEFAULT_ACTION_END) {
if (dom_string_isequal(type, corestring_dom_DOMNodeInserted)) {
return dom_default_action_DOMNodeInserted_cb;
+ } else if (dom_string_isequal(type, corestring_dom_DOMNodeInsertedIntoDocument)) {
+ return dom_default_action_DOMNodeInsertedIntoDocument_cb;
} else if (dom_string_isequal(type, corestring_dom_DOMSubtreeModified)) {
return dom_default_action_DOMSubtreeModified_cb;
}
@@ -847,6 +980,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->parser = NULL;
c->parse_completed = false;
+ c->conversion_begun = false;
c->document = NULL;
c->quirks = DOM_DOCUMENT_QUIRKS_MODE_NONE;
c->encoding = NULL;
@@ -862,6 +996,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->stylesheet_count = 0;
c->stylesheets = NULL;
c->select_ctx = NULL;
+ c->media.type = CSS_MEDIA_SCREEN;
c->universal = NULL;
c->num_objects = 0;
c->object_list = NULL;
@@ -948,6 +1083,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
(void *) &old_node_data);
if (err != DOM_NO_ERR) {
dom_hubbub_parser_destroy(c->parser);
+ c->parser = NULL;
nsurl_unref(c->base_url);
c->base_url = NULL;
@@ -996,14 +1132,14 @@ html_create(const content_handler *handler,
error = html_create_html_data(html, params);
if (error != NSERROR_OK) {
- content_broadcast_errorcode(&html->base, error);
+ content_broadcast_error(&html->base, error, NULL);
free(html);
return error;
}
error = html_css_new_stylesheets(html);
if (error != NSERROR_OK) {
- content_broadcast_errorcode(&html->base, error);
+ content_broadcast_error(&html->base, error, NULL);
free(html);
return error;
}
@@ -1024,8 +1160,8 @@ html_process_encoding_change(struct content *c,
dom_hubbub_parser_params parse_params;
dom_hubbub_error error;
const char *encoding;
- const char *source_data;
- unsigned long source_size;
+ const uint8_t *source_data;
+ size_t source_size;
/* Retrieve new encoding */
encoding = dom_hubbub_parser_get_encoding(html->parser,
@@ -1091,7 +1227,7 @@ html_process_encoding_change(struct content *c,
* it cannot be changed again.
*/
error = dom_hubbub_parser_parse_chunk(html->parser,
- (const uint8_t *)source_data,
+ source_data,
source_size);
return libdom_hubbub_error_to_nserror(error);
@@ -1122,7 +1258,7 @@ html_process_data(struct content *c, const char *data, unsigned int size)
/* broadcast the error if necessary */
if (err != NSERROR_OK) {
- content_broadcast_errorcode(c, err);
+ content_broadcast_error(c, err, NULL);
return false;
}
@@ -1185,14 +1321,17 @@ bool html_can_begin_conversion(html_content *htmlc)
{
unsigned int i;
+ /* Cannot begin conversion if we're still fetching stuff */
if (htmlc->base.active != 0)
return false;
for (i = 0; i != htmlc->stylesheet_count; i++) {
+ /* Cannot begin conversion if the stylesheets are modified */
if (htmlc->stylesheets[i].modified)
return false;
}
+ /* All is good, begin */
return true;
}
@@ -1221,11 +1360,19 @@ html_begin_conversion(html_content *htmlc)
NSLOG(netsurf, INFO, "Completing parse (%p)", htmlc);
/* complete parsing */
error = dom_hubbub_parser_completed(htmlc->parser);
+ if (error == DOM_HUBBUB_HUBBUB_ERR_PAUSED && htmlc->base.active > 0) {
+ /* The act of completing the parse failed because we've
+ * encountered a sync script which needs to run
+ */
+ NSLOG(netsurf, INFO, "Completing parse brought synchronous JS to light, cannot complete yet");
+ return true;
+ }
if (error != DOM_HUBBUB_OK) {
NSLOG(netsurf, INFO, "Parsing failed");
- content_broadcast_errorcode(&htmlc->base,
- libdom_hubbub_error_to_nserror(error));
+ content_broadcast_error(&htmlc->base,
+ libdom_hubbub_error_to_nserror(error),
+ NULL);
return false;
}
@@ -1243,12 +1390,15 @@ html_begin_conversion(html_content *htmlc)
NSLOG(netsurf, INFO, "Conversion aborted (%p) (active: %u)",
htmlc, htmlc->base.active);
content_set_error(&htmlc->base);
- content_broadcast_errorcode(&htmlc->base, NSERROR_STOPPED);
+ content_broadcast_error(&htmlc->base, NSERROR_STOPPED, NULL);
return false;
}
- /* complete script execution */
- html_script_exec(htmlc);
+ /* Conversion begins proper at this point */
+ htmlc->conversion_begun = true;
+
+ /* complete script execution, including deferred scripts */
+ html_script_exec(htmlc, true);
/* fire a simple event that bubbles named DOMContentLoaded at
* the Document.
@@ -1261,15 +1411,17 @@ html_begin_conversion(html_content *htmlc)
encoding = dom_hubbub_parser_get_encoding(htmlc->parser,
&htmlc->encoding_source);
if (encoding == NULL) {
- content_broadcast_errorcode(&htmlc->base,
- NSERROR_NOMEM);
+ content_broadcast_error(&htmlc->base,
+ NSERROR_NOMEM,
+ NULL);
return false;
}
htmlc->encoding = strdup(encoding);
if (htmlc->encoding == NULL) {
- content_broadcast_errorcode(&htmlc->base,
- NSERROR_NOMEM);
+ content_broadcast_error(&htmlc->base,
+ NSERROR_NOMEM,
+ NULL);
return false;
}
}
@@ -1278,7 +1430,7 @@ html_begin_conversion(html_content *htmlc)
exc = dom_document_get_document_element(htmlc->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
NSLOG(netsurf, INFO, "error retrieving html element from dom");
- content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
+ content_broadcast_error(&htmlc->base, NSERROR_DOM, NULL);
return false;
}
@@ -1288,7 +1440,7 @@ html_begin_conversion(html_content *htmlc)
(!dom_string_caseless_lwc_isequal(node_name,
corestring_lwc_html))) {
NSLOG(netsurf, INFO, "root element not html");
- content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
+ content_broadcast_error(&htmlc->base, NSERROR_DOM, NULL);
dom_node_unref(html);
return false;
}
@@ -1314,7 +1466,7 @@ html_begin_conversion(html_content *htmlc)
}
if (ns_error != NSERROR_OK) {
- content_broadcast_errorcode(&htmlc->base, ns_error);
+ content_broadcast_error(&htmlc->base, ns_error, NULL);
dom_node_unref(html);
return false;
@@ -1324,8 +1476,9 @@ html_begin_conversion(html_content *htmlc)
f->action = strdup(nsurl_access(action));
nsurl_unref(action);
if (f->action == NULL) {
- content_broadcast_errorcode(&htmlc->base,
- NSERROR_NOMEM);
+ content_broadcast_error(&htmlc->base,
+ NSERROR_NOMEM,
+ NULL);
dom_node_unref(html);
return false;
@@ -1335,8 +1488,9 @@ html_begin_conversion(html_content *htmlc)
if (f->document_charset == NULL) {
f->document_charset = strdup(htmlc->encoding);
if (f->document_charset == NULL) {
- content_broadcast_errorcode(&htmlc->base,
- NSERROR_NOMEM);
+ content_broadcast_error(&htmlc->base,
+ NSERROR_NOMEM,
+ NULL);
dom_node_unref(html);
return false;
}
@@ -1416,8 +1570,8 @@ static void html_reformat(struct content *c, int width, int height)
htmlc->reflowing = true;
- htmlc->len_ctx.vw = width;
- htmlc->len_ctx.vh = height;
+ htmlc->len_ctx.vw = nscss_pixels_physical_to_css(INTTOFIX(width));
+ htmlc->len_ctx.vh = nscss_pixels_physical_to_css(INTTOFIX(height));
htmlc->len_ctx.root_style = htmlc->layout->style;
layout_document(htmlc, width, height);
@@ -1440,11 +1594,12 @@ static void html_reformat(struct content *c, int width, int height)
selection_reinit(&htmlc->sel, htmlc->layout);
htmlc->reflowing = false;
+ htmlc->had_initial_layout = true;
/* calculate next reflow time at three times what it took to reflow */
nsu_getmonotonic_ms(&ms_after);
- ms_interval = (ms_before - ms_after) * 3;
+ ms_interval = (ms_after - ms_before) * 3;
if (ms_interval < (nsoption_uint(min_reflow_period) * 10)) {
ms_interval = nsoption_uint(min_reflow_period) * 10;
}
@@ -1557,6 +1712,13 @@ static void html_destroy(struct content *c)
NSLOG(netsurf, INFO, "content %p", c);
+ /* If we're still converting a layout, cancel it */
+ if (html->box_conversion_context != NULL) {
+ if (cancel_dom_to_box(html->box_conversion_context) != NSERROR_OK) {
+ NSLOG(netsurf, CRITICAL, "WARNING, Unable to cancel conversion context, browser may crash");
+ }
+ }
+
/* Destroy forms */
for (f = html->forms; f != NULL; f = g) {
g = f->prev;
@@ -1654,7 +1816,7 @@ static nserror html_clone(const struct content *old, struct content **newc)
* Handle a window containing a CONTENT_HTML being opened.
*/
-static void
+static nserror
html_open(struct content *c,
struct browser_window *bw,
struct content *page,
@@ -1674,6 +1836,8 @@ html_open(struct content *c,
html->selection_owner.none = true;
html_object_open_objects(html, bw);
+
+ return NSERROR_OK;
}
@@ -1681,7 +1845,7 @@ html_open(struct content *c,
* Handle a window containing a CONTENT_HTML being closed.
*/
-static void html_close(struct content *c)
+static nserror html_close(struct content *c)
{
html_content *htmlc = (html_content *) c;
@@ -1702,6 +1866,8 @@ static void html_close(struct content *c)
/* remove all object references from the html content */
html_object_close_objects(htmlc);
+
+ return NSERROR_OK;
}
@@ -1801,8 +1967,11 @@ html_get_contextual_content(struct content *c, int x, int y,
}
if (box->iframe) {
+ float scale = browser_window_get_scale(box->iframe);
browser_window_get_features(box->iframe,
- x - box_x, y - box_y, data);
+ (x - box_x) * scale,
+ (y - box_y) * scale,
+ data);
}
if (box->object)
@@ -1877,9 +2046,15 @@ html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry)
continue;
/* Pass into iframe */
- if (box->iframe && browser_window_scroll_at_point(box->iframe,
- x - box_x, y - box_y, scrx, scry) == true)
- return true;
+ if (box->iframe) {
+ float scale = browser_window_get_scale(box->iframe);
+
+ if (browser_window_scroll_at_point(box->iframe,
+ (x - box_x) * scale,
+ (y - box_y) * scale,
+ scrx, scry) == true)
+ return true;
+ }
/* Pass into textarea widget */
if (box->gadget && (box->gadget->type == GADGET_TEXTAREA ||
@@ -2015,15 +2190,21 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
&box_x, &box_y)) != NULL) {
box = next;
- if (box->style && css_computed_visibility(box->style) ==
- CSS_VISIBILITY_HIDDEN)
+ if (box->style &&
+ css_computed_visibility(box->style) == CSS_VISIBILITY_HIDDEN)
continue;
- if (box->iframe)
- return browser_window_drop_file_at_point(box->iframe,
- x - box_x, y - box_y, file);
+ if (box->iframe) {
+ float scale = browser_window_get_scale(box->iframe);
+ return browser_window_drop_file_at_point(
+ box->iframe,
+ (x - box_x) * scale,
+ (y - box_y) * scale,
+ file);
+ }
- if (box->object && content_drop_file_at_point(box->object,
+ if (box->object &&
+ content_drop_file_at_point(box->object,
x - box_x, y - box_y, file) == true)
return true;
@@ -2400,6 +2581,90 @@ bool html_get_id_offset(hlcache_handle *h, lwc_string *frag_id, int *x, int *y)
return false;
}
+static bool html_exec(struct content *c, const char *src, size_t srclen)
+{
+ html_content *htmlc = (html_content *)c;
+ bool result = false;
+ dom_exception err;
+ dom_html_body_element *body_node;
+ dom_string *dom_src;
+ dom_text *text_node;
+ dom_node *spare_node;
+ dom_html_script_element *script_node;
+
+ if (htmlc->document == NULL) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, no document");
+ goto out_no_string;
+ }
+
+ err = dom_string_create((const uint8_t *)src, srclen, &dom_src);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, could not create string");
+ goto out_no_string;
+ }
+
+ err = dom_html_document_get_body(htmlc->document, &body_node);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to retrieve body element");
+ goto out_no_body;
+ }
+
+ err = dom_document_create_text_node(htmlc->document, dom_src, &text_node);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, could not create text node");
+ goto out_no_text_node;
+ }
+
+ err = dom_document_create_element(htmlc->document, corestring_dom_SCRIPT, &script_node);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, could not create script node");
+ goto out_no_script_node;
+ }
+
+ err = dom_node_append_child(script_node, text_node, &spare_node);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, could not insert code node into script node");
+ goto out_unparented;
+ }
+ dom_node_unref(spare_node); /* We do not need the spare ref at all */
+
+ err = dom_node_append_child(body_node, script_node, &spare_node);
+ if (err != DOM_NO_ERR) {
+ NSLOG(netsurf, DEEPDEBUG, "Unable to exec, could not insert script node into document body");
+ goto out_unparented;
+ }
+ dom_node_unref(spare_node); /* Again no need for the spare ref */
+
+ /* We successfully inserted the node into the DOM */
+
+ result = true;
+
+ /* Now we unwind, starting by removing the script from wherever it
+ * ended up parented
+ */
+
+ err = dom_node_get_parent_node(script_node, &spare_node);
+ if (err == DOM_NO_ERR && spare_node != NULL) {
+ dom_node *second_spare;
+ err = dom_node_remove_child(spare_node, script_node, &second_spare);
+ if (err == DOM_NO_ERR) {
+ dom_node_unref(second_spare);
+ }
+ dom_node_unref(spare_node);
+ }
+
+out_unparented:
+ dom_node_unref(script_node);
+out_no_script_node:
+ dom_node_unref(text_node);
+out_no_text_node:
+ dom_node_unref(body_node);
+out_no_body:
+ dom_string_unref(dom_src);
+out_no_string:
+ return result;
+}
+
/**
* Compute the type of a content
*
@@ -2442,6 +2707,7 @@ static const content_handler html_content_handler = {
.clone = html_clone,
.get_encoding = html_encoding,
.type = html_content_type,
+ .exec = html_exec,
.no_share = true,
};
diff --git a/content/handlers/html/html_css.c b/content/handlers/html/html_css.c
index 7b2d469..eb80c0e 100644
--- a/content/handlers/html/html_css.c
+++ b/content/handlers/html/html_css.c
@@ -21,6 +21,8 @@
* Processing for html content css operations.
*/
+#define _GNU_SOURCE /* strcasestr needs this for string.h */
+
#include <assert.h>
#include <ctype.h>
#include <stdint.h>
@@ -114,10 +116,8 @@ html_convert_css_callback(hlcache_handle *css,
case CONTENT_MSG_ERROR:
NSLOG(netsurf, INFO, "stylesheet %s failed: %s",
nsurl_access(hlcache_handle_get_url(css)),
- event->data.error);
- /* fall through */
+ event->data.errordata.errormsg);
- case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(css);
s->sheet = NULL;
parent->base.active--;
@@ -238,7 +238,7 @@ html_create_style_element(html_content *c, dom_node *style)
(c->stylesheet_count + 1));
if (stylesheets == NULL) {
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return false;
}
@@ -262,7 +262,7 @@ static bool html_css_process_modified_style(html_content *c,
error = html_stylesheet_from_domnode(c, s->node, &sheet);
if (error != NSERROR_OK) {
NSLOG(netsurf, INFO, "Failed to update sheet");
- content_broadcast_errorcode(&c->base, error);
+ content_broadcast_error(&c->base, error, NULL);
return false;
}
@@ -470,7 +470,7 @@ bool html_css_process_link(html_content *htmlc, dom_node *node)
return true;
no_memory:
- content_broadcast_errorcode(&htmlc->base, ns_error);
+ content_broadcast_error(&htmlc->base, ns_error, NULL);
return false;
}
@@ -631,6 +631,9 @@ html_css_new_selection_context(html_content *c, css_select_ctx **ret_select_ctx)
css_origin origin = CSS_ORIGIN_AUTHOR;
/* Filter out stylesheets for non-screen media. */
+ /* TODO: We should probably pass the sheet in anyway, and let
+ * libcss handle the filtering.
+ */
if (hsheet->unused) {
continue;
}
@@ -646,10 +649,13 @@ html_css_new_selection_context(html_content *c, css_select_ctx **ret_select_ctx)
}
if (sheet != NULL) {
+ /* TODO: Pass the sheet's full media query, instead of
+ * "screen".
+ */
css_ret = css_select_ctx_append_sheet(select_ctx,
sheet,
origin,
- CSS_MEDIA_SCREEN);
+ "screen");
if (css_ret != CSS_OK) {
css_select_ctx_destroy(select_ctx);
return css_error_to_nserror(css_ret);
diff --git a/content/handlers/html/html_forms.c b/content/handlers/html/html_forms.c
index 915eb00..896263d 100644
--- a/content/handlers/html/html_forms.c
+++ b/content/handlers/html/html_forms.c
@@ -391,7 +391,18 @@ parse_input_element(struct form *forms, dom_html_input_element *input)
control = NULL;
goto out;
}
+
+ control->last_synced_value = strdup(control->value);
+ if (control->last_synced_value == NULL) {
+ form_free_control(control);
+ control = NULL;
+ goto out;
+ }
+
+ control->node_value = dom_string_ref(ds_value);
}
+ /* Force the gadget and DOM to be in sync */
+ form_gadget_sync_with_dom(control);
}
if (form != NULL && control != NULL)
diff --git a/content/handlers/html/html_interaction.c b/content/handlers/html/html_interaction.c
index 648d274..d31ad1d 100644
--- a/content/handlers/html/html_interaction.c
+++ b/content/handlers/html/html_interaction.c
@@ -382,13 +382,15 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
int padding_left, padding_right, padding_top, padding_bottom;
browser_drag_type drag_type = browser_window_get_drag_type(bw);
union content_msg_data msg_data;
- struct dom_node *node = NULL;
+ struct dom_node *node = html->layout->node; /* Default to the <HTML> */
union html_drag_owner drag_owner;
union html_selection_owner sel_owner;
bool click = mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2 |
BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2 |
BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2);
+ nserror res = NSERROR_OK;
+
if (drag_type != DRAGGING_NONE && !mouse &&
html->visible_select_menu != NULL) {
/* drag end: select menu */
@@ -410,11 +412,13 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
} else {
int width, height;
+ struct hlcache_handle *bw_content;
form_select_get_dimensions(html->visible_select_menu,
&width, &height);
html->visible_select_menu = NULL;
- browser_window_redraw_rect(bw, box_x, box_y,
- width, height);
+ bw_content = browser_window_get_content(bw);
+ content_request_redraw(bw_content,box_x, box_y,
+ width, height);
}
return;
}
@@ -841,16 +845,15 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
browser_window_get_position(iframe, false, &pos_x, &pos_y);
- pos_x /= scale;
- pos_y /= scale;
-
if (mouse & BROWSER_MOUSE_CLICK_1 ||
- mouse & BROWSER_MOUSE_CLICK_2) {
+ mouse & BROWSER_MOUSE_CLICK_2) {
browser_window_mouse_click(iframe, mouse,
- x - pos_x, y - pos_y);
+ (x * scale) - pos_x,
+ (y * scale) - pos_y);
} else {
browser_window_mouse_track(iframe, mouse,
- x - pos_x, y - pos_y);
+ (x * scale) - pos_x,
+ (y * scale) - pos_y);
}
} else if (html_object_box) {
@@ -875,9 +878,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
}
} else if (url) {
if (nsoption_bool(display_decoded_idn) == true) {
- if (nsurl_get_utf8(url, &url_s, &url_l) != NSERROR_OK) {
- /* Unable to obtain a decoded IDN. This is not a fatal error.
- * Ensure the string pointer is NULL so we use the encoded version. */
+ res = nsurl_get_utf8(url, &url_s, &url_l);
+ if (res != NSERROR_OK) {
+ /* Unable to obtain a decoded IDN. This is not
+ * a fatal error. Ensure the string pointer
+ * is NULL so we use the encoded version.
+ */
url_s = NULL;
}
}
@@ -1072,22 +1078,32 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
*/
switch (action) {
case ACTION_SUBMIT:
- form_submit(content_get_url(c),
- browser_window_find_target(bw, target, mouse),
- gadget->form, gadget);
+ res = form_submit(content_get_url(c),
+ browser_window_find_target(bw, target, mouse),
+ gadget->form,
+ gadget);
break;
+
case ACTION_GO:
- browser_window_navigate(browser_window_find_target(bw, target, mouse),
- url,
- content_get_url(c),
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
+ res = browser_window_navigate(
+ browser_window_find_target(bw, target, mouse),
+ url,
+ content_get_url(c),
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
break;
+
case ACTION_NONE:
+ res = NSERROR_OK;
break;
}
+
+ if (res != NSERROR_OK) {
+ guit->misc->warning(messages_get_errorcode(res), NULL);
+ }
+
}
@@ -1149,21 +1165,25 @@ bool html_keypress(struct content *c, uint32_t key)
/**
* Handle search.
*
- * \param c content of type HTML
- * \param context front end private data
- * \param flags search flags
- * \param string search string
+ * \param c content of type HTML
+ * \param context front end private data
+ * \param flags search flags
+ * \param string search string
*/
-void html_search(struct content *c, void *context,
- search_flags_t flags, const char *string)
+void
+html_search(struct content *c,
+ void *context,
+ search_flags_t flags,
+ const char *string)
{
html_content *html = (html_content *)c;
assert(c != NULL);
- if (string != NULL && html->search_string != NULL &&
- strcmp(string, html->search_string) == 0 &&
- html->search != NULL) {
+ if ((string != NULL) &&
+ (html->search_string != NULL) &&
+ (strcmp(string, html->search_string) == 0) &&
+ (html->search != NULL)) {
/* Continue prev. search */
search_step(html->search, flags, string);
diff --git a/content/handlers/html/html_internal.h b/content/handlers/html/html_internal.h
index 77354c3..fd6354a 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -98,6 +98,7 @@ typedef struct html_content {
dom_hubbub_parser *parser; /**< Parser object handle */
bool parse_completed; /**< Whether the parse has been completed */
+ bool conversion_begun; /**< Whether or not the conversion has begun */
/** Document tree */
dom_document *document;
@@ -126,6 +127,9 @@ typedef struct html_content {
/** Whether a layout (reflow) is in progress */
bool reflowing;
+ /** Whether an initial layout has been done */
+ bool had_initial_layout;
+
/** Whether scripts are enabled for this content */
bool enable_scripting;
@@ -134,6 +138,10 @@ typedef struct html_content {
/** A talloc context purely for the render box tree */
int *bctx;
+ /** A context pointer for the box conversion, NULL if no conversion
+ * is in progress.
+ */
+ void *box_conversion_context;
/** Box tree, or NULL. */
struct box *layout;
/** Document background colour. */
@@ -155,6 +163,8 @@ typedef struct html_content {
struct html_stylesheet *stylesheets;
/**< Style selection context */
css_select_ctx *select_ctx;
+ /**< Style selection media specification */
+ css_media media;
/**< Universal selector */
lwc_string *universal;
@@ -313,9 +323,10 @@ dom_hubbub_error html_process_script(void *ctx, dom_node *node);
* http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.h...
*
* \param htmlc html content.
+ * \param allow_defer allow deferred execution, if not, only async scripts.
* \return NSERROR_OK error code.
*/
-nserror html_script_exec(html_content *htmlc);
+nserror html_script_exec(html_content *htmlc, bool allow_defer);
/**
* Free all script resources and references for a html content.
diff --git a/content/handlers/html/html_object.c b/content/handlers/html/html_object.c
index 7eab466..37bf29f 100644
--- a/content/handlers/html/html_object.c
+++ b/content/handlers/html/html_object.c
@@ -137,9 +137,7 @@ html_object_callback(hlcache_handle *object,
struct box *box;
box = o->box;
- if (box == NULL &&
- event->type != CONTENT_MSG_ERROR &&
- event->type != CONTENT_MSG_ERRORCODE) {
+ if (box == NULL && event->type != CONTENT_MSG_ERROR) {
return NSERROR_OK;
}
@@ -166,7 +164,7 @@ html_object_callback(hlcache_handle *object,
c->base.status == CONTENT_STATUS_DONE)
content__reformat(&c->base, false,
c->base.available_width,
- c->base.height);
+ c->base.available_height);
}
break;
@@ -180,6 +178,10 @@ html_object_callback(hlcache_handle *object,
box->flags & REPLACE_DIM) {
union content_msg_data data;
+ if (c->had_initial_layout == false) {
+ break;
+ }
+
if (!box_visible(box))
break;
@@ -195,7 +197,6 @@ html_object_callback(hlcache_handle *object,
}
break;
- case CONTENT_MSG_ERRORCODE:
case CONTENT_MSG_ERROR:
hlcache_handle_release(object);
@@ -215,6 +216,10 @@ html_object_callback(hlcache_handle *object,
if (c->base.status != CONTENT_STATUS_LOADING) {
union content_msg_data data = event->data;
+ if (c->had_initial_layout == false) {
+ break;
+ }
+
if (!box_visible(box))
break;
@@ -354,6 +359,13 @@ html_object_callback(hlcache_handle *object,
*(event->data.jscontext) = NULL;
break;
+ case CONTENT_MSG_GETDIMS:
+ *(event->data.getdims.viewport_width) =
+ content__get_width(&c->base);
+ *(event->data.getdims.viewport_height) =
+ content__get_height(&c->base);
+ break;
+
case CONTENT_MSG_SCROLL:
if (box->scroll_x != NULL)
scrollbar_set(box->scroll_x, event->data.scroll.x0,
@@ -455,11 +467,10 @@ html_object_callback(hlcache_handle *object,
c->base.active == 0 &&
(event->type == CONTENT_MSG_LOADING ||
event->type == CONTENT_MSG_DONE ||
- event->type == CONTENT_MSG_ERROR ||
- event->type == CONTENT_MSG_ERRORCODE)) {
+ event->type == CONTENT_MSG_ERROR)) {
/* all objects have arrived */
content__reformat(&c->base, false, c->base.available_width,
- c->base.height);
+ c->base.available_height);
content_set_done(&c->base);
} else if (nsoption_bool(incremental_reflow) &&
event->type == CONTENT_MSG_DONE &&
@@ -484,7 +495,7 @@ html_object_callback(hlcache_handle *object,
content__reformat(&c->base,
false,
c->base.available_width,
- c->base.height);
+ c->base.available_height);
}
}
diff --git a/content/handlers/html/html_redraw.c b/content/handlers/html/html_redraw.c
index d05df87..6216d60 100644
--- a/content/handlers/html/html_redraw.c
+++ b/content/handlers/html/html_redraw.c
@@ -1786,8 +1786,8 @@ bool html_redraw_box(const html_content *html, struct box *box,
} else if (box->iframe) {
/* Offset is passed to browser window redraw unscaled */
browser_window_redraw(box->iframe,
- (x + padding_left) / scale,
- (y + padding_top) / scale, &r, ctx);
+ x + padding_left,
+ y + padding_top, &r, ctx);
} else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) {
if (!html_redraw_checkbox(x + padding_left, y + padding_top,
diff --git a/content/handlers/html/html_script.c b/content/handlers/html/html_script.c
index 80992b9..f7131e2 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -42,7 +42,7 @@
#include "html/html.h"
#include "html/html_internal.h"
-typedef bool (script_handler_t)(struct jscontext *jscontext, const char *data, size_t size) ;
+typedef bool (script_handler_t)(struct jscontext *jscontext, const uint8_t *data, size_t size, const char *name);
static script_handler_t *select_script_handler(content_type ctype)
@@ -55,7 +55,7 @@ static script_handler_t *select_script_handler(content_type ctype)
/* exported internal interface documented in html/html_internal.h */
-nserror html_script_exec(html_content *c)
+nserror html_script_exec(html_content *c, bool allow_defer)
{
unsigned int i;
struct html_script *s;
@@ -71,7 +71,7 @@ nserror html_script_exec(html_content *c)
}
if ((s->type == HTML_SCRIPT_ASYNC) ||
- (s->type == HTML_SCRIPT_DEFER)) {
+ (allow_defer && (s->type == HTML_SCRIPT_DEFER))) {
/* ensure script content is present */
if (s->data.handle == NULL)
continue;
@@ -90,11 +90,17 @@ nserror html_script_exec(html_content *c)
if (content_get_status(s->data.handle) ==
CONTENT_STATUS_DONE) {
/* external script is now available */
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
data = content_get_source_data(
s->data.handle, &size );
- script_handler(c->jscontext, data, size);
+ script_handler(c->jscontext, data, size,
+ nsurl_access(hlcache_handle_get_url(s->data.handle)));
+ /* We have to re-acquire this here since the
+ * c->scripts array may have been reallocated
+ * as a result of executing this script.
+ */
+ s = &(c->scripts[i]);
s->already_started = true;
@@ -177,10 +183,8 @@ convert_script_async_cb(hlcache_handle *script,
case CONTENT_MSG_ERROR:
NSLOG(netsurf, INFO, "script %s failed: %s",
nsurl_access(hlcache_handle_get_url(script)),
- event->data.error);
- /* fall through */
+ event->data.errordata.errormsg);
- case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
@@ -200,6 +204,13 @@ convert_script_async_cb(hlcache_handle *script,
html_begin_conversion(parent);
}
+ /* if we have already started converting though, then we can handle the
+ * scripts as they come in.
+ */
+ else if (parent->conversion_begun) {
+ html_script_exec(parent, false);
+ }
+
return NSERROR_OK;
}
@@ -236,10 +247,8 @@ convert_script_defer_cb(hlcache_handle *script,
case CONTENT_MSG_ERROR:
NSLOG(netsurf, INFO, "script %s failed: %s",
nsurl_access(hlcache_handle_get_url(script)),
- event->data.error);
- /* fall through */
+ event->data.errordata.errormsg);
- case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
@@ -297,16 +306,19 @@ convert_script_sync_cb(hlcache_handle *script,
script_handler = select_script_handler(content_get_type(s->data.handle));
if (script_handler != NULL && parent->jscontext != NULL) {
/* script has a handler */
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
data = content_get_source_data(s->data.handle, &size );
- script_handler(parent->jscontext, data, size);
+ script_handler(parent->jscontext, data, size,
+ nsurl_access(hlcache_handle_get_url(s->data.handle)));
}
/* continue parse */
- err = dom_hubbub_parser_pause(parent->parser, false);
- if (err != DOM_HUBBUB_OK) {
- NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ if (parent->parser != NULL) {
+ err = dom_hubbub_parser_pause(parent->parser, false);
+ if (err != DOM_HUBBUB_OK) {
+ NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ }
}
break;
@@ -314,10 +326,8 @@ convert_script_sync_cb(hlcache_handle *script,
case CONTENT_MSG_ERROR:
NSLOG(netsurf, INFO, "script %s failed: %s",
nsurl_access(hlcache_handle_get_url(script)),
- event->data.error);
- /* fall through */
+ event->data.errordata.errormsg);
- case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
@@ -328,9 +338,11 @@ convert_script_sync_cb(hlcache_handle *script,
s->already_started = true;
/* continue parse */
- err = dom_hubbub_parser_pause(parent->parser, false);
- if (err != DOM_HUBBUB_OK) {
- NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ if (parent->parser != NULL) {
+ err = dom_hubbub_parser_pause(parent->parser, false);
+ if (err != DOM_HUBBUB_OK) {
+ NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ }
}
break;
@@ -372,7 +384,7 @@ exec_src_script(html_content *c,
/* src url */
ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined);
if (ns_error != NSERROR_OK) {
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return DOM_HUBBUB_NOMEM;
}
@@ -402,6 +414,12 @@ exec_src_script(html_content *c,
return DOM_HUBBUB_OK; /* dom error */
}
+ if (c->parse_completed) {
+ /* After parse completed, all scripts are essentially async */
+ async = true;
+ defer = false;
+ }
+
if (async) {
/* asyncronous script */
script_type = HTML_SCRIPT_ASYNC;
@@ -428,7 +446,7 @@ exec_src_script(html_content *c,
nscript = html_process_new_script(c, mimetype, script_type);
if (nscript == NULL) {
nsurl_unref(joined);
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return DOM_HUBBUB_NOMEM;
}
@@ -498,7 +516,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
if (nscript == NULL) {
dom_string_unref(script);
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return DOM_HUBBUB_NOMEM;
}
@@ -513,8 +531,9 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
if (script_handler != NULL) {
script_handler(c->jscontext,
- dom_string_data(script),
- dom_string_byte_length(script));
+ (const uint8_t *)dom_string_data(script),
+ dom_string_byte_length(script),
+ "?inline script?");
}
return DOM_HUBBUB_OK;
}
@@ -580,16 +599,21 @@ nserror html_script_free(html_content *html)
dom_string_unref(html->scripts[i].mimetype);
}
- if ((html->scripts[i].type == HTML_SCRIPT_INLINE) &&
- (html->scripts[i].data.string != NULL)) {
-
- dom_string_unref(html->scripts[i].data.string);
-
- } else if ((html->scripts[i].type == HTML_SCRIPT_SYNC) &&
- (html->scripts[i].data.handle != NULL)) {
-
- hlcache_handle_release(html->scripts[i].data.handle);
-
+ switch (html->scripts[i].type) {
+ case HTML_SCRIPT_INLINE:
+ if (html->scripts[i].data.string != NULL) {
+ dom_string_unref(html->scripts[i].data.string);
+ }
+ break;
+ case HTML_SCRIPT_SYNC:
+ /* fallthrough */
+ case HTML_SCRIPT_ASYNC:
+ /* fallthrough */
+ case HTML_SCRIPT_DEFER:
+ if (html->scripts[i].data.handle != NULL) {
+ hlcache_handle_release(html->scripts[i].data.handle);
+ }
+ break;
}
}
free(html->scripts);
diff --git a/content/handlers/html/imagemap.c b/content/handlers/html/imagemap.c
index d26ba5f..0c35768 100644
--- a/content/handlers/html/imagemap.c
+++ b/content/handlers/html/imagemap.c
@@ -376,14 +376,14 @@ imagemap_addtolist(const struct html_content *c,
}
if (target != NULL) {
- /* Copy target into the map */
+ /* Copy target dom string into the map data */
new_map->target = malloc(dom_string_byte_length(target) + 1);
if (new_map->target == NULL)
goto bad_out;
- strncpy(new_map->target,
- dom_string_data(target),
- dom_string_byte_length(target));
+ memcpy(new_map->target,
+ dom_string_data(target),
+ dom_string_byte_length(target));
new_map->target[dom_string_byte_length(target)] = 0;
}
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index d52dbf8..611c778 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -220,6 +220,11 @@ layout_get_object_dimensions(struct box *box,
int intrinsic_width = content_get_width(box->object);
int intrinsic_height = content_get_height(box->object);
+ if (min_width > 0 && min_width > *width)
+ *width = min_width;
+ if (max_width >= 0 && max_width < *width)
+ *width = max_width;
+
if (intrinsic_width != 0)
*height = (*width * intrinsic_height) /
intrinsic_width;
@@ -5390,6 +5395,10 @@ bool layout_document(html_content *content, int width, int height)
struct box *doc = content->layout;
const struct gui_layout_table *font_func = content->font_func;
+ NSLOG(layout, DEBUG, "Doing layout to %ix%i of %s",
+ width, height, nsurl_access(content_get_url(
+ &content->base)));
+
layout_minmax_block(doc, font_func, content);
layout_block_find_dimensions(&content->len_ctx,
diff --git a/content/handlers/html/search.c b/content/handlers/html/search.c
index 9ba2957..3599951 100644
--- a/content/handlers/html/search.c
+++ b/content/handlers/html/search.c
@@ -75,8 +75,8 @@ struct search_context {
/* Exported function documented in search.h */
-struct search_context * search_create_context(struct content *c,
- content_type type, void *gui_data)
+struct search_context *
+search_create_context(struct content *c, content_type type, void *gui_data)
{
struct search_context *context;
struct list_entry *search_head;
@@ -422,6 +422,49 @@ static bool find_occurrences_text(const char *pattern, int p_len,
/**
+ * Specifies whether all matches or just the current match should
+ * be highlighted in the search text.
+ */
+static void search_show_all(bool all, struct search_context *context)
+{
+ struct list_entry *a;
+
+ for (a = context->found->next; a; a = a->next) {
+ bool add = true;
+ if (!all && a != context->current) {
+ add = false;
+ if (a->sel) {
+ selection_clear(a->sel, true);
+ selection_destroy(a->sel);
+ a->sel = NULL;
+ }
+ }
+ if (add && !a->sel) {
+
+ if (context->is_html == true) {
+ html_content *html = (html_content *)context->c;
+ a->sel = selection_create(context->c, true);
+ if (!a->sel)
+ continue;
+
+ selection_init(a->sel, html->layout,
+ &html->len_ctx);
+ } else {
+ a->sel = selection_create(context->c, false);
+ if (!a->sel)
+ continue;
+
+ selection_init(a->sel, NULL, NULL);
+ }
+
+ selection_set_start(a->sel, a->start_idx);
+ selection_set_end(a->sel, a->end_idx);
+ }
+ }
+}
+
+
+/**
* Search for a string in the box tree
*
* \param string the string to search for
@@ -429,8 +472,11 @@ static bool find_occurrences_text(const char *pattern, int p_len,
* \param context The search context to add the entry to.
* \param flags flags to control the search.
*/
-static void search_text(const char *string, int string_len,
- struct search_context *context, search_flags_t flags)
+static void
+search_text(const char *string,
+ int string_len,
+ struct search_context *context,
+ search_flags_t flags)
{
struct rect bounds;
struct box *box = NULL;
@@ -456,7 +502,8 @@ static void search_text(const char *string, int string_len,
/* check if we need to start a new search or continue an old one */
- if (context->newsearch) {
+ if ((context->newsearch) ||
+ (context->prev_case_sens != case_sensitive)) {
bool res;
if (context->string != NULL)
@@ -543,16 +590,15 @@ static void search_text(const char *string, int string_len,
/* Exported function documented in search.h */
-void search_step(struct search_context *context, search_flags_t flags,
- const char *string)
+void
+search_step(struct search_context *context,
+ search_flags_t flags,
+ const char *string)
{
int string_len;
int i = 0;
- if (context == NULL) {
- guit->misc->warning("SearchError", 0);
- return;
- }
+ assert(context != NULL);
guit->search->add_recent(string, context->gui_p);
@@ -598,44 +644,6 @@ bool search_term_highlighted(struct content *c,
}
-/* Exported function documented in search.h */
-void search_show_all(bool all, struct search_context *context)
-{
- struct list_entry *a;
-
- for (a = context->found->next; a; a = a->next) {
- bool add = true;
- if (!all && a != context->current) {
- add = false;
- if (a->sel) {
- selection_clear(a->sel, true);
- selection_destroy(a->sel);
- a->sel = NULL;
- }
- }
- if (add && !a->sel) {
-
- if (context->is_html == true) {
- html_content *html = (html_content *)context->c;
- a->sel = selection_create(context->c, true);
- if (!a->sel)
- continue;
-
- selection_init(a->sel, html->layout,
- &html->len_ctx);
- } else {
- a->sel = selection_create(context->c, false);
- if (!a->sel)
- continue;
-
- selection_init(a->sel, NULL, NULL);
- }
-
- selection_set_start(a->sel, a->start_idx);
- selection_set_end(a->sel, a->end_idx);
- }
- }
-}
/* Exported function documented in search.h */
diff --git a/content/handlers/html/search.h b/content/handlers/html/search.h
index 5c9408e..dfb1afc 100644
--- a/content/handlers/html/search.h
+++ b/content/handlers/html/search.h
@@ -60,11 +60,6 @@ void search_destroy_context(struct search_context *context);
void search_step(struct search_context *context, search_flags_t flags,
const char * string);
-/**
- * Specifies whether all matches or just the current match should
- * be highlighted in the search text.
- */
-void search_show_all(bool all, struct search_context *context);
/**
* Determines whether any portion of the given text box should be
diff --git a/content/handlers/image/Makefile b/content/handlers/image/Makefile
index 541cd2c..1c27f74 100644
--- a/content/handlers/image/Makefile
+++ b/content/handlers/image/Makefile
@@ -3,13 +3,15 @@
# S_IMAGE are sources related to image management
S_IMAGE_YES := image.c image_cache.c
S_IMAGE_NO :=
-S_IMAGE_$(NETSURF_USE_BMP) += bmp.c ico.c
+S_IMAGE_$(NETSURF_USE_BMP) += bmp.c
S_IMAGE_$(NETSURF_USE_GIF) += gif.c
+S_IMAGE_$(NETSURF_USE_BMP) += ico.c
S_IMAGE_$(NETSURF_USE_JPEG) += jpeg.c
S_IMAGE_$(NETSURF_USE_ROSPRITE) += nssprite.c
S_IMAGE_$(NETSURF_USE_PNG) += png.c
S_IMAGE_$(NETSURF_USE_NSSVG) += svg.c
S_IMAGE_$(NETSURF_USE_RSVG) += rsvg.c
S_IMAGE_$(NETSURF_USE_VIDEO) += video.c
+S_IMAGE_$(NETSURF_USE_WEBP) += webp.c
S_IMAGE := $(S_IMAGE_YES)
diff --git a/content/handlers/image/bmp.c b/content/handlers/image/bmp.c
index 48a37fb..448728e 100644
--- a/content/handlers/image/bmp.c
+++ b/content/handlers/image/bmp.c
@@ -78,7 +78,7 @@ static nserror nsbmp_create_bmp_data(nsbmp_content *bmp)
bmp->bmp = calloc(sizeof(struct bmp_image), 1);
if (bmp->bmp == NULL) {
- content_broadcast_errorcode(&bmp->base, NSERROR_NOMEM);
+ content_broadcast_error(&bmp->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
@@ -122,8 +122,8 @@ static bool nsbmp_convert(struct content *c)
nsbmp_content *bmp = (nsbmp_content *) c;
bmp_result res;
uint32_t swidth;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
char *title;
/* set the bmp data */
@@ -135,11 +135,11 @@ static bool nsbmp_convert(struct content *c)
case BMP_OK:
break;
case BMP_INSUFFICIENT_MEMORY:
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
case BMP_INSUFFICIENT_DATA:
case BMP_DATA_ERROR:
- content_broadcast_errorcode(c, NSERROR_BMP_ERROR);
+ content_broadcast_error(c, NSERROR_BMP_ERROR, NULL);
return false;
}
diff --git a/content/handlers/image/gif.c b/content/handlers/image/gif.c
index 253265c..94f8d3f 100644
--- a/content/handlers/image/gif.c
+++ b/content/handlers/image/gif.c
@@ -84,7 +84,7 @@ static nserror nsgif_create_gif_data(nsgif_content *c)
/* Initialise our data structure */
c->gif = calloc(sizeof(gif_animation), 1);
if (c->gif == NULL) {
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
gif_create(c->gif, &gif_bitmap_callbacks);
@@ -236,8 +236,8 @@ static bool nsgif_convert(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
int res;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
char *title;
/* Get the animation */
@@ -259,7 +259,7 @@ static bool nsgif_convert(struct content *c)
error = NSERROR_NOMEM;
break;
}
- content_broadcast_errorcode(c, error);
+ content_broadcast_error(c, error, NULL);
return false;
}
} while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA);
@@ -267,7 +267,7 @@ static bool nsgif_convert(struct content *c)
/* Abort on bad GIFs */
if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) ||
(gif->gif->height == 0)) {
- content_broadcast_errorcode(c, NSERROR_GIF_ERROR);
+ content_broadcast_error(c, NSERROR_GIF_ERROR, NULL);
return false;
}
diff --git a/content/handlers/image/ico.c b/content/handlers/image/ico.c
index 85aab9f..1f32063 100644
--- a/content/handlers/image/ico.c
+++ b/content/handlers/image/ico.c
@@ -75,7 +75,7 @@ static nserror nsico_create_ico_data(nsico_content *c)
c->ico = calloc(sizeof(ico_collection), 1);
if (c->ico == NULL) {
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
ico_collection_create(c->ico, &bmp_bitmap_callbacks);
@@ -120,8 +120,8 @@ static bool nsico_convert(struct content *c)
nsico_content *ico = (nsico_content *) c;
struct bmp_image *bmp;
bmp_result res;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
char *title;
/* set the ico data */
@@ -134,11 +134,11 @@ static bool nsico_convert(struct content *c)
case BMP_OK:
break;
case BMP_INSUFFICIENT_MEMORY:
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
case BMP_INSUFFICIENT_DATA:
case BMP_DATA_ERROR:
- content_broadcast_errorcode(c, NSERROR_ICO_ERROR);
+ content_broadcast_error(c, NSERROR_ICO_ERROR, NULL);
return false;
}
diff --git a/content/handlers/image/image.c b/content/handlers/image/image.c
index 675fdd6..4eb366e 100644
--- a/content/handlers/image/image.c
+++ b/content/handlers/image/image.c
@@ -35,6 +35,7 @@
#include "image/png.h"
#include "image/rsvg.h"
#include "image/svg.h"
+#include "image/webp.h"
#include "image/image.h"
/**
@@ -94,6 +95,12 @@ nserror image_init(void)
return error;
#endif
+#ifdef WITH_WEBP
+ error = nswebp_init();
+ if (error != NSERROR_OK)
+ return error;
+#endif
+
return error;
}
diff --git a/content/handlers/image/jpeg.c b/content/handlers/image/jpeg.c
index 6eec61c..8689acb 100644
--- a/content/handlers/image/jpeg.c
+++ b/content/handlers/image/jpeg.c
@@ -162,11 +162,14 @@ static void nsjpeg_error_exit(j_common_ptr cinfo)
longjmp(*setjmp_buffer, 1);
}
+/**
+ * create a bitmap from jpeg content.
+ */
static struct bitmap *
jpeg_cache_convert(struct content *c)
{
- uint8_t *source_data; /* Jpeg source data */
- unsigned long source_size; /* length of Jpeg source data */
+ const uint8_t *source_data; /* Jpeg source data */
+ size_t source_size; /* length of Jpeg source data */
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
jmp_buf setjmp_buffer;
@@ -185,7 +188,7 @@ jpeg_cache_convert(struct content *c)
nsjpeg_term_source };
/* obtain jpeg source data and perfom minimal sanity checks */
- source_data = (uint8_t *)content__get_source_data(c, &source_size);
+ source_data = content__get_source_data(c, &source_size);
if ((source_data == NULL) ||
(source_size < MIN_JPEG_SIZE)) {
@@ -312,8 +315,8 @@ static bool nsjpeg_convert(struct content *c)
nsjpeg_skip_input_data, jpeg_resync_to_restart,
nsjpeg_term_source };
union content_msg_data msg_data;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
char *title;
/* check image header is valid and get width/height */
@@ -326,7 +329,8 @@ static bool nsjpeg_convert(struct content *c)
if (setjmp(setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
- msg_data.error = nsjpeg_error_buffer;
+ msg_data.errordata.errorcode = NSERROR_UNKNOWN;
+ msg_data.errordata.errormsg = nsjpeg_error_buffer;
content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
diff --git a/content/handlers/image/nssprite.c b/content/handlers/image/nssprite.c
index 269c243..5f55495 100644
--- a/content/handlers/image/nssprite.c
+++ b/content/handlers/image/nssprite.c
@@ -98,8 +98,8 @@ static bool nssprite_convert(struct content *c)
struct rosprite_mem_context* ctx = NULL;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
char *title;
data = content__get_source_data(c, &size);
@@ -117,12 +117,12 @@ static bool nssprite_convert(struct content *c)
nssprite->bitmap = guit->bitmap->create(sprite->width, sprite->height, BITMAP_NEW);
if (!nssprite->bitmap) {
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
}
uint32_t* imagebuf = (uint32_t *)guit->bitmap->get_buffer(nssprite->bitmap);
if (!imagebuf) {
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
}
unsigned char *spritebuf = (unsigned char *)sprite->image;
@@ -165,7 +165,7 @@ ro_sprite_error:
if (ctx != NULL) {
rosprite_destroy_mem_context(ctx);
}
- content_broadcast_errorcode(c, NSERROR_SPRITE_ERROR);
+ content_broadcast_error(c, NSERROR_SPRITE_ERROR, NULL);
return false;
}
diff --git a/content/handlers/image/png.c b/content/handlers/image/png.c
index 7a4ce30..cf8e780 100644
--- a/content/handlers/image/png.c
+++ b/content/handlers/image/png.c
@@ -242,7 +242,7 @@ static nserror nspng_create_png_data(nspng_content *png_c)
png_c->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (png_c->png == NULL) {
- content_broadcast_errorcode(&png_c->base, NSERROR_NOMEM);
+ content_broadcast_error(&png_c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
@@ -252,7 +252,7 @@ static nserror nspng_create_png_data(nspng_content *png_c)
if (png_c->info == NULL) {
png_destroy_read_struct(&png_c->png, &png_c->info, 0);
- content_broadcast_errorcode(&png_c->base, NSERROR_NOMEM);
+ content_broadcast_error(&png_c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
@@ -262,7 +262,7 @@ static nserror nspng_create_png_data(nspng_content *png_c)
png_c->png = NULL;
png_c->info = NULL;
- content_broadcast_errorcode(&png_c->base, NSERROR_PNG_ERROR);
+ content_broadcast_error(&png_c->base, NSERROR_PNG_ERROR, NULL);
return NSERROR_NOMEM;
}
@@ -355,7 +355,7 @@ static bool nspng_process_data(struct content *c, const char *data,
png_c->png = NULL;
png_c->info = NULL;
- content_broadcast_errorcode(c, NSERROR_PNG_ERROR);
+ content_broadcast_error(c, NSERROR_PNG_ERROR, NULL);
ret = false;
@@ -367,8 +367,8 @@ static bool nspng_process_data(struct content *c, const char *data,
}
struct png_cache_read_data_s {
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
};
/** PNG library read fucntion to read data from a memory array
@@ -551,8 +551,8 @@ static nserror nspng_clone(const struct content *old_c, struct content **new_c)
{
nspng_content *clone_png_c;
nserror error;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
clone_png_c = calloc(1, sizeof(nspng_content));
if (clone_png_c == NULL)
@@ -573,7 +573,7 @@ static nserror nspng_clone(const struct content *old_c, struct content **new_c)
data = content__get_source_data(&clone_png_c->base, &size);
if (size > 0) {
- if (nspng_process_data(&clone_png_c->base, data, size) == false) {
+ if (nspng_process_data(&clone_png_c->base, (const char *)data, size) == false) {
content_destroy(&clone_png_c->base);
return NSERROR_NOMEM;
}
diff --git a/content/handlers/image/rsvg.c b/content/handlers/image/rsvg.c
index 2ba1b49..c7cb625 100644
--- a/content/handlers/image/rsvg.c
+++ b/content/handlers/image/rsvg.c
@@ -71,7 +71,7 @@ static nserror rsvg_create_svg_data(rsvg_content *c)
if ((c->rsvgh = rsvg_handle_new()) == NULL) {
NSLOG(netsurf, INFO, "rsvg_handle_new() returned NULL.");
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
@@ -120,7 +120,7 @@ static bool rsvg_process_data(struct content *c, const char *data,
&err) == FALSE) {
NSLOG(netsurf, INFO,
"rsvg_handle_write returned an error: %s", err->message);
- content_broadcast_errorcode(c, NSERROR_SVG_ERROR);
+ content_broadcast_error(c, NSERROR_SVG_ERROR, NULL);
return false;
}
@@ -171,7 +171,7 @@ static bool rsvg_convert(struct content *c)
if (rsvg_handle_close(d->rsvgh, &err) == FALSE) {
NSLOG(netsurf, INFO,
"rsvg_handle_close returned an error: %s", err->message);
- content_broadcast_errorcode(c, NSERROR_SVG_ERROR);
+ content_broadcast_error(c, NSERROR_SVG_ERROR, NULL);
return false;
}
@@ -189,7 +189,7 @@ static bool rsvg_convert(struct content *c)
BITMAP_NEW)) == NULL) {
NSLOG(netsurf, INFO,
"Failed to create bitmap for rsvg render.");
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
}
@@ -200,14 +200,14 @@ static bool rsvg_convert(struct content *c)
guit->bitmap->get_rowstride(d->bitmap))) == NULL) {
NSLOG(netsurf, INFO,
"Failed to create Cairo image surface for rsvg render.");
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
}
if ((d->ct = cairo_create(d->cs)) == NULL) {
NSLOG(netsurf, INFO,
"Failed to create Cairo drawing context for rsvg render.");
- content_broadcast_errorcode(c, NSERROR_NOMEM);
+ content_broadcast_error(c, NSERROR_NOMEM, NULL);
return false;
}
@@ -262,8 +262,8 @@ static nserror rsvg_clone(const struct content *old, struct content **newc)
{
rsvg_content *svg;
nserror error;
- const char *data;
- unsigned long size;
+ const uint8_t *data;
+ size_t size;
svg = calloc(1, sizeof(rsvg_content));
if (svg == NULL)
@@ -284,7 +284,7 @@ static nserror rsvg_clone(const struct content *old, struct content **newc)
data = content__get_source_data(&svg->base, &size);
if (size > 0) {
- if (rsvg_process_data(&svg->base, data, size) == false) {
+ if (rsvg_process_data(&svg->base, (const char *)data, size) == false) {
content_destroy(&svg->base);
return NSERROR_NOMEM;
}
diff --git a/content/handlers/image/svg.c b/content/handlers/image/svg.c
index 5126073..5124360 100644
--- a/content/handlers/image/svg.c
+++ b/content/handlers/image/svg.c
@@ -59,7 +59,7 @@ static nserror svg_create_svg_data(svg_content *c)
return NSERROR_OK;
no_memory:
- content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
+ content_broadcast_error(&c->base, NSERROR_NOMEM, NULL);
return NSERROR_NOMEM;
}
@@ -126,8 +126,8 @@ static bool svg_convert(struct content *c)
static void svg_reformat(struct content *c, int width, int height)
{
svg_content *svg = (svg_content *) c;
- const char *source_data;
- unsigned long source_size;
+ const uint8_t *source_data;
+ size_t source_size;
assert(svg->diagram);
@@ -135,9 +135,12 @@ static void svg_reformat(struct content *c, int width, int height)
if (width != svg->current_width || height != svg->current_height) {
source_data = content__get_source_data(c, &source_size);
- svgtiny_parse(svg->diagram, source_data, source_size,
- nsurl_access(content_get_url(c)),
- width, height);
+ svgtiny_parse(svg->diagram,
+ (const char *)source_data,
+ source_size,
+ nsurl_access(content_get_url(c)),
+ width,
+ height);
svg->current_width = width;
svg->current_height = height;
@@ -189,7 +192,7 @@ svg_redraw_internal(struct content *c,
for (i = 0; i != diagram->shape_count; i++) {
if (diagram->shape[i].path) {
pstyle.stroke_width = plot_style_int_to_fixed(
- diagram->shape[i].stroke);
+ diagram->shape[i].stroke_width);
pstyle.stroke_colour = BGR(diagram->shape[i].stroke);
pstyle.fill_colour = BGR(diagram->shape[i].fill);
res = ctx->plot->path(ctx,
@@ -222,7 +225,7 @@ svg_redraw_internal(struct content *c,
return false;
}
}
- }
+ }
#undef BGR
@@ -361,5 +364,3 @@ static const char *svg_types[] = {
CONTENT_FACTORY_REGISTER_TYPES(svg, svg_types, svg_content_handler);
-
-
diff --git a/content/handlers/image/webp.c b/content/handlers/image/webp.c
new file mode 100644
index 0000000..cbcb5ce
--- /dev/null
+++ b/content/handlers/image/webp.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2019 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * implementation of content handling for image/webp
+ *
+ * This implementation uses the google webp library.
+ * Image cache handling is performed by the generic NetSurf handler.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#include <webp/decode.h>
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "netsurf/bitmap.h"
+#include "content/llcache.h"
+#include "content/content_protected.h"
+#include "desktop/gui_internal.h"
+
+#include "image/image_cache.h"
+
+#include "webp.h"
+
+/**
+ * Content create entry point.
+ *
+ * create a content object for the webp
+ */
+static nserror
+webp_create(const content_handler *handler,
+ lwc_string *imime_type,
+ const struct http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset,
+ bool quirks,
+ struct content **c)
+{
+ struct content *webp_c; /* webp content object */
+ nserror res;
+
+ webp_c = calloc(1, sizeof(struct content));
+ if (webp_c == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = content__init(webp_c,
+ handler,
+ imime_type,
+ params,
+ llcache,
+ fallback_charset,
+ quirks);
+ if (res != NSERROR_OK) {
+ free(webp_c);
+ return res;
+ }
+
+ *c = webp_c;
+
+ return NSERROR_OK;
+}
+
+/**
+ * create a bitmap from webp content.
+ */
+static struct bitmap *
+webp_cache_convert(struct content *c)
+{
+ const uint8_t *source_data; /* webp source data */
+ size_t source_size; /* length of webp source data */
+ VP8StatusCode webpres;
+ WebPBitstreamFeatures webpfeatures;
+ unsigned int bmap_flags;
+ uint8_t *pixels = NULL;
+ uint8_t *decoded;
+ size_t rowstride;
+ struct bitmap *bitmap = NULL;
+
+ source_data = content__get_source_data(c, &source_size);
+
+ webpres = WebPGetFeatures(source_data, source_size, &webpfeatures);
+
+ if (webpres != VP8_STATUS_OK) {
+ return NULL;
+ }
+
+ if (webpfeatures.has_alpha == 0) {
+ bmap_flags = BITMAP_NEW | BITMAP_OPAQUE;
+ } else {
+ bmap_flags = BITMAP_NEW;
+ }
+
+ /* create bitmap */
+ bitmap = guit->bitmap->create(webpfeatures.width,
+ webpfeatures.height,
+ bmap_flags);
+ if (bitmap == NULL) {
+ /* empty bitmap could not be created */
+ return NULL;
+ }
+
+ pixels = guit->bitmap->get_buffer(bitmap);
+ if (pixels == NULL) {
+ /* bitmap with no buffer available */
+ guit->bitmap->destroy(bitmap);
+ return NULL;
+ }
+
+ rowstride = guit->bitmap->get_rowstride(bitmap);
+
+ decoded = WebPDecodeBGRAInto(source_data,
+ source_size,
+ pixels,
+ webpfeatures.width * webpfeatures.height * 4,
+ rowstride);
+ if (decoded == NULL) {
+ /* decode failed */
+ guit->bitmap->destroy(bitmap);
+ return NULL;
+ }
+
+ return bitmap;
+}
+
+/**
+ * Convert the webp source data content.
+ *
+ * This ensures there is valid webp source data in the content object
+ * and then adds it to the image cache ready to be converted on
+ * demand.
+ *
+ * \param c The webp content object
+ * \return true on successful processing of teh webp content else false
+ */
+static bool webp_convert(struct content *c)
+{
+ int res;
+ const uint8_t* data;
+ size_t data_size;
+ int width;
+ int height;
+
+ data = content__get_source_data(c, &data_size);
+
+ res = WebPGetInfo(data, data_size, &width, &height);
+ if (res == 0) {
+ NSLOG(netsurf, INFO, "WebPGetInfo failed:%p", c);
+ return false;
+ }
+
+ c->width = width;
+ c->height = height;
+ c->size = c->width * c->height * 4;
+
+ image_cache_add(c, NULL, webp_cache_convert);
+
+ content_set_ready(c);
+ content_set_done(c);
+
+ return true;
+}
+
+/**
+ * Clone content.
+ */
+static nserror webp_clone(const struct content *old, struct content **new_c)
+{
+ struct content *webp_c; /* cloned webp content */
+ nserror res;
+
+ webp_c = calloc(1, sizeof(struct content));
+ if (webp_c == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = content__clone(old, webp_c);
+ if (res != NSERROR_OK) {
+ content_destroy(webp_c);
+ return res;
+ }
+
+ /* re-convert if the content is ready */
+ if ((old->status == CONTENT_STATUS_READY) ||
+ (old->status == CONTENT_STATUS_DONE)) {
+ if (webp_convert(webp_c) == false) {
+ content_destroy(webp_c);
+ return NSERROR_CLONE_FAILED;
+ }
+ }
+
+ *new_c = webp_c;
+
+ return NSERROR_OK;
+}
+
+static const content_handler webp_content_handler = {
+ .create = webp_create,
+ .data_complete = webp_convert,
+ .destroy = image_cache_destroy,
+ .redraw = image_cache_redraw,
+ .clone = webp_clone,
+ .get_internal = image_cache_get_internal,
+ .type = image_cache_content_type,
+ .no_share = false,
+};
+
+static const char *webp_types[] = {
+ "image/webp"
+};
+
+CONTENT_FACTORY_REGISTER_TYPES(nswebp, webp_types, webp_content_handler);
diff --git a/content/handlers/pdf/pdf.h b/content/handlers/image/webp.h
similarity index 78%
copy from content/handlers/pdf/pdf.h
copy to content/handlers/image/webp.h
index 2171b80..b219f25 100644
--- a/content/handlers/pdf/pdf.h
+++ b/content/handlers/image/webp.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Vincent Sanders <vince(a)netsurf-browser.org>
+ * Copyright 2019 Vincent Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,12 +18,12 @@
/**
* \file
- * Interface for PDF content handler.
+ * Interface to image/webp content handlers
*/
-#ifndef NETSURF_PDF_PDF_H_
-#define NETSURF_PDF_PDF_H_
+#ifndef _NETSURF_IMAGE_WEBP_H_
+#define _NETSURF_IMAGE_WEBP_H_
-nserror nspdf_init(void);
+nserror nswebp_init(void);
#endif
diff --git a/content/handlers/javascript/content.c b/content/handlers/javascript/content.c
index ef56140..2cb5ecd 100644
--- a/content/handlers/javascript/content.c
+++ b/content/handlers/javascript/content.c
@@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Content for javascript (implementation)
+/**
+ * \file
+ * javascript content implementation
*/
#include <assert.h>
diff --git a/content/handlers/javascript/duktape/Console.bnd b/content/handlers/javascript/duktape/Console.bnd
index c4c0c83..3de875a 100644
--- a/content/handlers/javascript/duktape/Console.bnd
+++ b/content/handlers/javascript/duktape/Console.bnd
@@ -13,28 +13,50 @@ class Console {
private unsigned int group;
prologue %{
#include <nsutils/time.h>
+#include "netsurf/browser_window.h"
#define CONSOLE_TIMERS MAGIC(ConsoleTimers)
static void
-write_log_entry(duk_context *ctx, unsigned int group, char logtype)
+write_log_entry(duk_context *ctx, unsigned int group, browser_window_console_flags flags)
{
/* objs... */
+ dukky_push_generics(ctx, "consoleFormatter");
+ duk_insert(ctx, 0);
+ if (dukky_pcall(ctx, duk_get_top(ctx) - 1, false)) {
+ /* Failed to convert somehow, oh dear, you get to keep
+ * all the pieces.
+ */
+ duk_pop(ctx);
+ duk_push_string(ctx, "Oh dear, formatter went banananas");
+ }
+ /* str?objs?... */
for (int i = 0; i < duk_get_top(ctx); ++i) {
(void)duk_safe_to_string(ctx, i);
}
/* strs... */
- duk_push_sprintf(ctx, "%c: ", logtype);
- duk_insert(ctx, 0);
- /* pfx strs... */
for (unsigned int u = 0; u < group; ++u) {
duk_push_lstring(ctx, " ", 1);
duk_insert(ctx, 0);
}
- /* spcs... pfx strs... */
+ /* spcs... strs... */
duk_concat(ctx, duk_get_top(ctx));
/* str */
- NSLOG(netsurf, INFO, "%s", duk_safe_to_string(ctx, 0));
+
+ duk_push_global_object(ctx);
+ duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
+ window_private_t *priv_win = duk_get_pointer(ctx, -1);
+ duk_pop(ctx);
+
+ duk_size_t msglen;
+ const char *msg = duk_safe_to_lstring(ctx, 0, &msglen);
+
+ if (priv_win == NULL ||
+ browser_window_console_log(priv_win->win, BW_CS_SCRIPT_CONSOLE,
+ msg, msglen,
+ flags) != NSERROR_OK) {
+ NSLOG(netsurf, DEBUG, "Unable to log: %s", duk_safe_to_string(ctx, 0));
+ }
}
%};
@@ -68,37 +90,37 @@ method Console::groupEnd ()
method Console::info()
%{
- write_log_entry(ctx, priv->group, 'I');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
return 0;
%}
method Console::debug()
%{
- write_log_entry(ctx, priv->group, 'D');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_DEBUG);
return 0;
%}
method Console::error()
%{
- write_log_entry(ctx, priv->group, 'E');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_ERROR);
return 0;
%}
method Console::log()
%{
- write_log_entry(ctx, priv->group, 'L');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_LOG);
return 0;
%}
method Console::warn()
%{
- write_log_entry(ctx, priv->group, 'W');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_WARN);
return 0;
%}
method Console::dir()
%{
- write_log_entry(ctx, priv->group, 'd');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
return 0;
%}
@@ -161,7 +183,7 @@ method Console::timeEnd()
duk_push_string(ctx, "Timer elapsed: ");
duk_insert(ctx, 0);
duk_push_sprintf(ctx, "%lu ms", (duk_uint_t)(time_ms - old_time_ms));
- write_log_entry(ctx, priv->group, 'T');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
return 0;
%}
@@ -172,6 +194,6 @@ method Console::trace ()
duk_safe_to_string(ctx, -1);
duk_insert(ctx, 0);
duk_set_top(ctx, 1);
- write_log_entry(ctx, priv->group, 'S');
+ write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
return 0;
%}
diff --git a/content/handlers/javascript/duktape/Document.bnd b/content/handlers/javascript/duktape/Document.bnd
index 5de7245..d9bff0a 100644
--- a/content/handlers/javascript/duktape/Document.bnd
+++ b/content/handlers/javascript/duktape/Document.bnd
@@ -35,7 +35,7 @@ method Document::write()
}
duk_concat(ctx, duk_get_top(ctx));
text = duk_safe_to_lstring(ctx, 0, &text_len);
- JS_LOG("Writing %*s", (int)text_len, text);
+ NSLOG(netsurf, DEBUG, "Writing %*s", (int)text_len, text);
err = dom_node_get_user_data(priv->parent.node,
corestring_dom___ns_key_html_content_data,
@@ -70,7 +70,7 @@ method Document::writeln()
duk_concat(ctx, duk_get_top(ctx));
text = duk_safe_to_lstring(ctx, 0, &text_len);
- JS_LOG("Writeln %*s", (int)text_len, text);
+ NSLOG(netsurf, DEBUG, "Writeln %*s", (int)text_len, text);
err = dom_node_get_user_data(priv->parent.node,
corestring_dom___ns_key_html_content_data,
&htmlc);
@@ -147,6 +147,62 @@ method Document::createElement()
return 1;
%}
+method Document::createElementNS()
+%{
+ dom_node *newnode;
+ dom_exception err;
+ duk_size_t text_len;
+ duk_size_t ns_len;
+ const char *ns = duk_safe_to_lstring(ctx, 0, &ns_len);
+ const char *text = duk_safe_to_lstring(ctx, 0, &text_len);
+ dom_string *text_str;
+ dom_string *ns_str;
+
+ err = dom_string_create((const uint8_t*)ns, ns_len, &ns_str);
+ if (err != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ err = dom_string_create((const uint8_t*)text, text_len, &text_str);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(ns_str);
+ return 0; /* coerced to undefined */
+ }
+
+ err = dom_document_create_element_ns(priv->parent.node,
+ ns_str,
+ text_str,
+ &newnode);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(ns_str);
+ dom_string_unref(text_str);
+ return 0; /* coerced to undefined */
+ }
+
+ dom_string_unref(text_str);
+ dom_string_unref(ns_str);
+
+ dukky_push_node(ctx, newnode);
+
+ dom_node_unref(newnode);
+
+ return 1;
+%}
+
+method Document::createDocumentFragment()
+%{
+ struct dom_document_fragment *frag = NULL;
+ dom_exception err;
+
+ err = dom_document_create_document_fragment(priv->parent.node, &frag);
+
+ if (err != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ dukky_push_node(ctx, (dom_node *)frag);
+
+ dom_node_unref(frag); /* The pushed node holds the reference now */
+
+ return 1;
+%}
+
getter Document::head()
%{
struct dom_nodelist *nodes;
@@ -290,10 +346,18 @@ method Document::getElementsByTagName()
if (nodes == NULL) return 0; /* coerced to undefined */
+ dukky_push_generics(ctx, "makeListProxy");
+
duk_push_pointer(ctx, nodes);
dukky_create_object(ctx, PROTO_NAME(NODELIST), 1);
dom_nodelist_unref(nodes);
- return 1;
+
+ if (dukky_pcall(ctx, 1, false) != 0) {
+ NSLOG(dukky, DEBUG, "Unable to construct nodelist?");
+ return 0; /* coerced to undefined */
+ }
+
+ return 1; /* The Proxy(NodeList) wrapper */
%}
getter Document::cookie()
@@ -310,8 +374,10 @@ getter Document::cookie()
if (cookie_str != NULL) {
duk_push_string(ctx, cookie_str);
free(cookie_str);
- return 1;
+ } else {
+ duk_push_string(ctx, "");
}
+ return 1;
} else {
NSLOG(netsurf, INFO,
"error getting htmlc. parent node:%p htmlc:%p",
@@ -320,6 +386,53 @@ getter Document::cookie()
return 0;
%}
+setter Document::cookie()
+%{
+ struct html_content *htmlc;
+ dom_exception err;
+
+ const char * cookie_str = duk_safe_to_string(ctx, 0);
+
+ err = dom_node_get_user_data(priv->parent.node,
+ corestring_dom___ns_key_html_content_data,
+ &htmlc);
+ if ((err == DOM_NO_ERR) && (htmlc != NULL)) {
+ /* At this point we need to get the given cookie string parsed
+ * and inserted into the urldb
+ */
+ bool ok = urldb_set_cookie(cookie_str, /* The cookie string to set */
+ /* The location to set the cookie for */
+ llcache_handle_get_url(htmlc->base.llcache),
+ NULL); /* The referer, which we trust */
+ if (!ok) {
+ NSLOG(netsurf, DEEPDEBUG, "unable to set cookie: %s", cookie_str);
+ /* However there's no useful way to signal that to JS */
+ }
+ } else {
+ NSLOG(netsurf, INFO,
+ "error getting htmlc. parent node:%p htmlc:%p",
+ priv->parent.node, htmlc);
+ }
+ return 0;
+%}
+
+method Document::createEvent ()
+%{
+ /* Create a new event, mark it untrusted since it's new from JS */
+ dom_event *evt = NULL;
+ dom_exception exc;
+
+ exc = dom_event_create(&evt);
+ if (exc != DOM_NO_ERR) return 0;
+ exc = dom_event_set_is_trusted(evt, false);
+ if (exc != DOM_NO_ERR) { dom_event_unref(evt); return 0; }
+
+ dukky_push_event(ctx, evt);
+
+ dom_event_unref(evt);
+ return 1;
+%}
+
getter Document::onabort();
setter Document::onabort();
getter Document::onautocompleteerror();
diff --git a/content/handlers/javascript/duktape/Element.bnd b/content/handlers/javascript/duktape/Element.bnd
index f7e3354..6702342 100644
--- a/content/handlers/javascript/duktape/Element.bnd
+++ b/content/handlers/javascript/duktape/Element.bnd
@@ -204,10 +204,18 @@ method Element::getElementsByTagName ()
tagname, &nlist);
dom_string_unref(tagname);
if (exc != DOM_NO_ERR) return 0;
+
+ dukky_push_generics(ctx, "makeListProxy");
+
duk_push_pointer(ctx, nlist);
dukky_create_object(ctx, PROTO_NAME(NODELIST), 1);
dom_nodelist_unref(nlist);
+ if (dukky_pcall(ctx, 1, false) != 0) {
+ NSLOG(dukky, DEBUG, "Unable to construct nodelist?");
+ return 0; /* coerced to undefined */
+ }
+
return 1;
%}
@@ -275,6 +283,9 @@ method Element::getAttribute()
const char *s = duk_safe_to_lstring(ctx, 0, &slen);
exc = dom_string_create((const uint8_t *)s, slen, &attr_name);
duk_pop(ctx);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
exc = dom_element_get_attribute(priv->parent.node,
attr_name, &attr_value);
@@ -328,6 +339,9 @@ method Element::hasAttribute()
const char *s = duk_safe_to_lstring(ctx, 0, &slen);
exc = dom_string_create((const uint8_t *)s, slen, &attr_name);
duk_pop(ctx);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
exc = dom_element_has_attribute(priv->parent.node,
attr_name, &res);
diff --git a/content/handlers/javascript/duktape/Event.bnd b/content/handlers/javascript/duktape/Event.bnd
index a0bc3c3..aa69daa 100644
--- a/content/handlers/javascript/duktape/Event.bnd
+++ b/content/handlers/javascript/duktape/Event.bnd
@@ -54,6 +54,8 @@ getter Event::target ()
if (exc != DOM_NO_ERR) return 0;
dukky_push_node(ctx, et);
+
+ dom_node_unref(et);
return 1;
%}
@@ -67,6 +69,8 @@ getter Event::currentTarget ()
if (exc != DOM_NO_ERR) return 0;
dukky_push_node(ctx, et);
+
+ dom_node_unref(et);
return 1;
%}
@@ -148,3 +152,40 @@ getter Event::defaultPrevented ()
return 1;
%}
+getter Event::isTrusted ()
+%{
+ dom_exception exc;
+ bool ret;
+
+ exc = dom_event_get_is_trusted(priv->evt, &ret);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_boolean(ctx, ret);
+ return 1;
+%}
+
+
+method Event::initEvent ()
+%{
+ dom_exception exc;
+ bool bubbles;
+ bool cancellable;
+
+ duk_size_t text_len;
+ const char *text = duk_safe_to_lstring(ctx, 0, &text_len);
+ dom_string *text_str;
+
+ exc = dom_string_create((const uint8_t*)text, text_len, &text_str);
+ if (exc != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ bubbles = duk_get_boolean(ctx, 1);
+ cancellable = duk_get_boolean(ctx, 2);
+
+ exc = dom_event_init(priv->evt, text_str, bubbles, cancellable);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(text_str);
+ return 0;
+ }
+
+ return 0;
+%}
diff --git a/content/handlers/javascript/duktape/HTMLBodyElement.bnd b/content/handlers/javascript/duktape/HTMLBodyElement.bnd
index a283f89..4787396 100644
--- a/content/handlers/javascript/duktape/HTMLBodyElement.bnd
+++ b/content/handlers/javascript/duktape/HTMLBodyElement.bnd
@@ -8,6 +8,13 @@
* http://www.opensource.org/licenses/mit-license
*/
+prologue HTMLBodyElement()
+%{
+#include "utils/corestrings.h"
+
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
+%}
+
init HTMLBodyElement(struct dom_html_element *html_body_element::html_element);
getter HTMLBodyElement::aLink();
@@ -22,3 +29,29 @@ getter HTMLBodyElement::text();
setter HTMLBodyElement::text();
getter HTMLBodyElement::vLink();
setter HTMLBodyElement::vLink();
+getter HTMLBodyElement::onafterprint();
+setter HTMLBodyElement::onafterprint();
+getter HTMLBodyElement::onbeforeprint();
+setter HTMLBodyElement::onbeforeprint();
+getter HTMLBodyElement::onbeforeunload();
+setter HTMLBodyElement::onbeforeunload();
+getter HTMLBodyElement::onhashchange();
+setter HTMLBodyElement::onhashchange();
+getter HTMLBodyElement::onlanguagechange();
+setter HTMLBodyElement::onlanguagechange();
+getter HTMLBodyElement::onmessage();
+setter HTMLBodyElement::onmessage();
+getter HTMLBodyElement::onoffline();
+setter HTMLBodyElement::onoffline();
+getter HTMLBodyElement::ononline();
+setter HTMLBodyElement::ononline();
+getter HTMLBodyElement::onpagehide();
+setter HTMLBodyElement::onpagehide();
+getter HTMLBodyElement::onpageshow();
+setter HTMLBodyElement::onpageshow();
+getter HTMLBodyElement::onpopstate();
+setter HTMLBodyElement::onpopstate();
+getter HTMLBodyElement::onstorage();
+setter HTMLBodyElement::onstorage();
+getter HTMLBodyElement::onunload();
+setter HTMLBodyElement::onunload();
diff --git a/content/handlers/javascript/duktape/HTMLFrameSetElement.bnd b/content/handlers/javascript/duktape/HTMLFrameSetElement.bnd
index cc66e93..e72c177 100644
--- a/content/handlers/javascript/duktape/HTMLFrameSetElement.bnd
+++ b/content/handlers/javascript/duktape/HTMLFrameSetElement.bnd
@@ -8,6 +8,13 @@
* http://www.opensource.org/licenses/mit-license
*/
+prologue HTMLFrameSetElement()
+%{
+#include "utils/corestrings.h"
+
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
+%}
+
init HTMLFrameSetElement(struct dom_html_element *html_frame_set_element::html_element);
getter HTMLFrameSetElement::cols();
@@ -15,3 +22,30 @@ setter HTMLFrameSetElement::cols();
getter HTMLFrameSetElement::rows();
setter HTMLFrameSetElement::rows();
+
+getter HTMLFrameSetElement::onafterprint();
+setter HTMLFrameSetElement::onafterprint();
+getter HTMLFrameSetElement::onbeforeprint();
+setter HTMLFrameSetElement::onbeforeprint();
+getter HTMLFrameSetElement::onbeforeunload();
+setter HTMLFrameSetElement::onbeforeunload();
+getter HTMLFrameSetElement::onhashchange();
+setter HTMLFrameSetElement::onhashchange();
+getter HTMLFrameSetElement::onlanguagechange();
+setter HTMLFrameSetElement::onlanguagechange();
+getter HTMLFrameSetElement::onmessage();
+setter HTMLFrameSetElement::onmessage();
+getter HTMLFrameSetElement::onoffline();
+setter HTMLFrameSetElement::onoffline();
+getter HTMLFrameSetElement::ononline();
+setter HTMLFrameSetElement::ononline();
+getter HTMLFrameSetElement::onpagehide();
+setter HTMLFrameSetElement::onpagehide();
+getter HTMLFrameSetElement::onpageshow();
+setter HTMLFrameSetElement::onpageshow();
+getter HTMLFrameSetElement::onpopstate();
+setter HTMLFrameSetElement::onpopstate();
+getter HTMLFrameSetElement::onstorage();
+setter HTMLFrameSetElement::onstorage();
+getter HTMLFrameSetElement::onunload();
+setter HTMLFrameSetElement::onunload();
diff --git a/content/handlers/javascript/duktape/Makefile b/content/handlers/javascript/duktape/Makefile
index 2a5c2e7..d15b712 100644
--- a/content/handlers/javascript/duktape/Makefile
+++ b/content/handlers/javascript/duktape/Makefile
@@ -4,10 +4,27 @@
# Included by javascript/Makefile
#
-content/handlers/javascript/duktape/dukky.c: $(OBJROOT)/duktape/binding.h
+content/handlers/javascript/duktape/dukky.c: \
+ $(OBJROOT)/duktape/binding.h \
+ $(OBJROOT)/duktape/generics.js.inc \
+ $(OBJROOT)/duktape/polyfill.js.inc
BINDINGS := $(wildcard content/handlers/javascript/duktape/*.bnd)
+# Generator for the C include representing the generics.js
+$(OBJROOT)/duktape/generics.js.inc: content/handlers/javascript/duktape/generics.js
+ $(Q)$(MKDIR) -p $(OBJROOT)/duktape
+ $(VQ)echo " XXD: $<"
+ $(Q)xxd -i $< $@.tmp
+ $(Q)sed -e 's/content_handlers_javascript_duktape_generics_js/generics_js/' $@.tmp > $@
+
+# Generator for the C include representing the polyfill.js
+$(OBJROOT)/duktape/polyfill.js.inc: content/handlers/javascript/duktape/polyfill.js
+ $(Q)$(MKDIR) -p $(OBJROOT)/duktape
+ $(VQ)echo " XXD: $<"
+ $(Q)xxd -i $< $@.tmp
+ $(Q)sed -e 's/content_handlers_javascript_duktape_polyfill_js/polyfill_js/' $@.tmp > $@
+
# ensure genbind generates debugging files
GBFLAGS+=-D
@@ -17,14 +34,18 @@ $(OBJROOT)/duktape/binding.h $(OBJROOT)/duktape/Makefile: content/handlers/javas
$(Q)nsgenbind $(GBFLAGS) -I content/handlers/javascript/WebIDL $< $(OBJROOT)/duktape
# create unimplemented report for doxygen
-Docs/UnimplementedJavascript.txt: content/handlers/javascript/duktape/netsurf.bnd $(BINDINGS)
+docs/UnimplementedJavascript.md: content/handlers/javascript/duktape/netsurf.bnd $(BINDINGS)
$(Q)$(MKDIR) -p $(OBJROOT)/duktape
- $(VQ)echo "/** \page unimplemented Unimplemented javascript bindings" > $@
+ $(VQ)echo "Unimplemented javascript bindings {#unimplemented}" > $@
+ $(VQ)echo "=================================" >> $@
+ $(VQ)echo "" >> $@
$(VQ)echo "This is a list of all the binding methods, getters and setters without an implementation in a binding." >> $@
$(VQ)echo "" >> $@
+ $(VQ)echo "Type | Unimplemented binding" >> $@
+ $(VQ)echo "---- | ---------------------" >> $@
$(VQ)echo " GENBIND: $<"
- $(Q)nsgenbind $(GBFLAGS) -Wunimplemented -I content/handlers/javascript/WebIDL $< $(OBJROOT)/duktape 2>&1 >/dev/null | grep "Unimplemented" | cut -d' ' -f4- | sort -k 2 | awk '{print $$0"\\n" }' >> $@
- $(VQ)echo "*/" >> $@
+ $(Q)nsgenbind $(GBFLAGS) -Wunimplemented -I content/handlers/javascript/WebIDL $< $(OBJROOT)/duktape 2>&1 >/dev/null | awk 'BEGIN{count=0} /.*Unimplemented.*/{count++; out=$$4" |"; for(i=5;i<=NF;i++){out=out" "$$i}; print out} END{print "\n",count,"unimplemented bindings"}' >> $@
+ $(VQ)echo "" >> $@
ifeq ($(filter $(MAKECMDGOALS),clean test coverage),)
-include $(OBJROOT)/duktape/Makefile
diff --git a/content/handlers/javascript/duktape/Node.bnd b/content/handlers/javascript/duktape/Node.bnd
index f14cfc1..98fb5dd 100644
--- a/content/handlers/javascript/duktape/Node.bnd
+++ b/content/handlers/javascript/duktape/Node.bnd
@@ -10,6 +10,9 @@
class Node {
private dom_node *node;
+ prologue %{
+
+%};
};
init Node(struct dom_node *node)
@@ -117,12 +120,17 @@ getter Node::childNodes()
duk_pop(ctx);
exc = dom_node_get_child_nodes(priv->node, &nlist);
if (exc != DOM_NO_ERR) return 0;
+ dukky_push_generics(ctx, "makeListProxy");
duk_push_pointer(ctx, nlist);
if (dukky_create_object(ctx, PROTO_NAME(NODELIST), 1) != DUK_EXEC_SUCCESS) {
dom_nodelist_unref(nlist);
return 0;
}
dom_nodelist_unref(nlist);
+ if (dukky_pcall(ctx, 1, false) != 0) {
+ NSLOG(dukky, DEBUG, "Unable to construct nodelist?");
+ return 0; /* coerced to undefined */
+ }
duk_dup(ctx, -1);
duk_put_prop_string(ctx, 0, MAGIC(childNodes));
}
@@ -427,6 +435,7 @@ method Node::appendChild()
dom_exception err;
dom_node *spare;
+ NSLOG(dukky, DEEPDEBUG, "About to append %p to %p", other->node, priv->node);
err = dom_node_append_child(priv->node, other->node, &spare);
if (err != DOM_NO_ERR) return 0;
dukky_push_node(ctx, spare);
diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd
index 98ba39d..478f92b 100644
--- a/content/handlers/javascript/duktape/Window.bnd
+++ b/content/handlers/javascript/duktape/Window.bnd
@@ -11,12 +11,235 @@
class Window {
private struct browser_window * win;
private struct html_content * htmlc;
+ private struct window_schedule_s * schedule_ring;
prologue %{
+#include "utils/corestrings.h"
#include "utils/nsurl.h"
#include "netsurf/browser_window.h"
#include "content/hlcache.h"
#include "html/html.h"
#include "html/html_internal.h"
+#include "desktop/gui_internal.h"
+#include "netsurf/misc.h"
+#include "utils/ring.h"
+#include "netsurf/inttypes.h"
+
+#define WINDOW_CALLBACKS MAGIC(WindowCallbacks)
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
+
+static size_t next_handle = 0;
+
+typedef struct window_schedule_s {
+ window_private_t *owner;
+ duk_context *ctx;
+ struct window_schedule_s *r_next;
+ struct window_schedule_s *r_prev;
+ size_t handle;
+ int repeat_timeout;
+ bool running;
+} window_schedule_t;
+
+static void window_remove_callback_bits(duk_context *ctx, size_t handle) {
+ /* stack is ... */
+ duk_push_global_object(ctx);
+ duk_get_prop_string(ctx, -1, WINDOW_CALLBACKS);
+ /* stack is ..., win, cbt */
+ duk_push_int(ctx, (duk_int_t)handle);
+ /* ..., win, cbt, handle */
+ duk_del_prop(ctx, -2);
+ /* ..., win, cbt */
+ duk_pop_2(ctx);
+ /* ... */
+}
+
+static void
+window_call_callback(duk_context *ctx, size_t handle, bool clear_entry)
+{
+ NSLOG(dukky, DEEPDEBUG, "ctx=%p, handle=%"PRIsizet, ctx, handle);
+ /* Stack is ... */
+ duk_push_global_object(ctx);
+ /* ..., win */
+ duk_get_prop_string(ctx, -1, WINDOW_CALLBACKS);
+ /* ..., win, cbt */
+ duk_push_int(ctx, (duk_int_t)handle);
+ /* ..., win, cbt, handle */
+ duk_get_prop(ctx, -2);
+ /* ..., win, cbt, cbo */
+ //dukky_log_stack_frame(ctx, "On entry to callback");
+ /* ..., win, cbt, cbo */
+ /* What we want to do is call cbo.func passing all of cbo.args */
+ duk_get_prop_string(ctx, -1, "func");
+ duk_get_prop_string(ctx, -2, "args");
+ /* ..., win, cbt, cbo, func, argarr */
+ duk_size_t arrlen = duk_get_length(ctx, -1);
+ for (duk_size_t i = 0; i < arrlen; ++i) {
+ duk_push_int(ctx, (duk_int_t)i);
+ duk_get_prop(ctx, -(2+i));
+ }
+ /* ..., win, cbt, cbo, func, argarr, args... */
+ duk_remove(ctx, -(arrlen+1));
+ /* ..., win, cbt, cbo, func, args... */
+ //dukky_log_stack_frame(ctx, "Just before call");
+ (void) dukky_pcall(ctx, arrlen, true);
+ /* ..., win, cbt, cbo, retval */
+ if (clear_entry) {
+ NSLOG(dukky, DEEPDEBUG, "Not recurring callback, removing from cbt");
+ duk_pop_n(ctx, 2);
+ /* ..., win, cbt */
+ duk_push_int(ctx, (duk_int_t)handle);
+ /* ..., win, cbt, handle */
+ duk_del_prop(ctx, -2);
+ /* ..., win, cbt */
+ duk_pop_n(ctx, 2);
+ } else {
+ duk_pop_n(ctx, 4);
+ }
+ /* ... */
+ //dukky_log_stack_frame(ctx, "On leaving callback");
+}
+
+
+static void
+window_schedule_callback(void *p)
+{
+ window_schedule_t *priv = (window_schedule_t *)p;
+
+ NSLOG(dukky, DEEPDEBUG,
+ "Entered window scheduler callback: %"PRIsizet, priv->handle);
+
+ priv->running = true;
+ window_call_callback(priv->ctx,
+ priv->handle,
+ priv->repeat_timeout == 0);
+ priv->running = false;
+
+ if (priv->repeat_timeout > 0) {
+ /* Reschedule */
+ NSLOG(dukky, DEEPDEBUG,
+ "Rescheduling repeating callback %"PRIsizet,
+ priv->handle);
+ guit->misc->schedule(priv->repeat_timeout,
+ window_schedule_callback,
+ priv);
+ } else {
+ NSLOG(dukky, DEEPDEBUG,
+ "Removing completed callback %"PRIsizet, priv->handle);
+ /* Remove this from the ring */
+ RING_REMOVE(priv->owner->schedule_ring, priv);
+ window_remove_callback_bits(priv->ctx, priv->handle);
+ free(priv);
+ }
+}
+
+static size_t
+window_alloc_new_callback(duk_context *ctx,
+ window_private_t *window,
+ bool repeating,
+ int timeout)
+{
+ size_t new_handle = next_handle++;
+ window_schedule_t *sched = calloc(sizeof *sched, 1);
+ if (sched == NULL) {
+ return new_handle;
+ }
+ sched->owner = window;
+ sched->ctx = ctx;
+ sched->handle = new_handle;
+ sched->repeat_timeout = repeating ? timeout : 0;
+ sched->running = false;
+
+ RING_INSERT(window->schedule_ring, sched);
+
+ /* Next, the duktape stack looks like: func, timeout, ...
+ * In order to proceed, we want to put into the WINDOW_CALLBACKS
+ * keyed by the handle, an object containing the call to make and
+ * the array of arguments to call the function with
+ */
+ duk_idx_t nargs = duk_get_top(ctx) - 2;
+ duk_push_global_object(ctx);
+ duk_get_prop_string(ctx, -1, WINDOW_CALLBACKS);
+ duk_push_int(ctx, (duk_int_t)new_handle);
+ duk_push_object(ctx);
+ /* stack is: func, timeout, ..., win, cbt, handle, cbo */
+
+ /* put the function into the cbo */
+ duk_dup(ctx, 0);
+ duk_put_prop_string(ctx, -2, "func");
+
+ /* Now the arguments */
+ duk_push_array(ctx);
+ for (duk_idx_t i = 0; i < nargs; ++i) {
+ duk_dup(ctx, 2 + i); /* Dup the arg */
+ duk_put_prop_index(ctx, -2, i); /* arr[i] = arg[i] */
+ }
+ duk_put_prop_string(ctx, -2, "args");
+ /* stack is: func, timeout, ..., win, cbt, handle, cbo */
+ duk_put_prop(ctx, -3);
+ /* stack is: func, timeout, ..., win, cbt */
+ duk_pop_2(ctx);
+ /* And we're back to func, timeout, ... */
+
+ guit->misc->schedule(timeout, window_schedule_callback, sched);
+ NSLOG(dukky, DEEPDEBUG, "Scheduled callback %"PRIsizet" for %d ms from now", new_handle, timeout);
+
+ return new_handle;
+}
+
+static void
+window_remove_callback_by_handle(duk_context *ctx,
+ window_private_t *window,
+ size_t handle)
+{
+ int res;
+
+ RING_ITERATE_START(window_schedule_t, window->schedule_ring, sched) {
+ if (sched->handle == handle) {
+ if (sched->running) {
+ NSLOG(dukky, DEEPDEBUG,
+ "Cancelling in-train callback %"PRIsizet,
+ sched->handle);
+ sched->repeat_timeout = 0;
+ } else {
+ NSLOG(dukky, DEEPDEBUG,
+ "Cancelled callback %"PRIsizet,
+ sched->handle);
+ res = guit->misc->schedule(-1,
+ window_schedule_callback,
+ sched);
+ assert(res == NSERROR_OK);
+ RING_REMOVE(window->schedule_ring, sched);
+ window_remove_callback_bits(ctx, sched->handle);
+ free(sched);
+ }
+ RING_ITERATE_STOP(window->schedule_ring, sched);
+ }
+ } RING_ITERATE_END(window->schedule_ring, sched);
+}
+
+/* This is the dodgy compartment closedown method */
+static duk_ret_t dukky_window_closedown_compartment(duk_context *ctx)
+{
+ window_private_t *priv = NULL;
+
+ duk_push_global_object(ctx);
+ duk_get_prop_string(ctx, -1, dukky_magic_string_private);
+ priv = duk_get_pointer(ctx, -1);
+ duk_pop_2(ctx);
+
+ if (priv == NULL) {
+ return 0;
+ }
+
+ NSLOG(dukky, DEEPDEBUG, "Closing down compartment");
+ while (priv->schedule_ring != NULL) {
+ window_remove_callback_by_handle(ctx,
+ priv,
+ priv->schedule_ring->handle);
+ }
+
+ return 0;
+}
+
%};
};
@@ -25,10 +248,22 @@ init Window(struct browser_window *win, struct html_content *htmlc)
/* element window */
priv->win = win;
priv->htmlc = htmlc;
- NSLOG(netsurf, INFO, "win=%p htmlc=%p", priv->win, priv->htmlc);
+ priv->schedule_ring = NULL;
+ NSLOG(netsurf, DEEPDEBUG, "win=%p htmlc=%p", priv->win, priv->htmlc);
- NSLOG(netsurf, INFO,
+ NSLOG(netsurf, DEEPDEBUG,
"URL is %s", nsurl_access(browser_window_access_url(priv->win)));
+ duk_push_object(ctx);
+ duk_put_prop_string(ctx, 0, WINDOW_CALLBACKS);
+%}
+
+fini Window()
+%{
+ NSLOG(dukky, DEEPDEBUG, "Shutting down Window %p", priv->win);
+ /* Cheaply iterate the schedule ring, cancelling any pending callbacks */
+ while (priv->schedule_ring != NULL) {
+ window_remove_callback_by_handle(ctx, priv, priv->schedule_ring->handle);
+ }
%}
prototype Window()
@@ -36,25 +271,112 @@ prototype Window()
#define EXPOSE(v) \
duk_get_global_string(ctx, #v); \
duk_put_prop_string(ctx, 0, #v)
- /* steal undefined */
+ /* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_... */
+ /* ** Value properties */
+ EXPOSE(infinity);
+ EXPOSE(NaN);
EXPOSE(undefined);
+ EXPOSE(null);
+ EXPOSE(globalThis);
+
+ /* ** Function properties */
EXPOSE(eval);
- EXPOSE(Object);
- EXPOSE(parseInt);
+ /* EXPOSE(uneval); */ /* Not standard, maybe not available */
+ EXPOSE(isFinite);
+ EXPOSE(isNaN);
EXPOSE(parseFloat);
- EXPOSE(Array);
+ EXPOSE(parseInt);
+ EXPOSE(decodeURI);
+ EXPOSE(decodeURIComponent);
+ EXPOSE(encodeURI);
+ EXPOSE(encodeURIComponent);
+ EXPOSE(escape);
+ EXPOSE(unescape);
+
+ /* ** Fundamental Objects */
+ EXPOSE(Object);
+ EXPOSE(Function);
+ EXPOSE(Boolean);
+ EXPOSE(Symbol);
+ EXPOSE(Error);
+ EXPOSE(EvalError);
+ EXPOSE(InternalError);
+ EXPOSE(RangeError);
+ EXPOSE(ReferenceError);
+ EXPOSE(SyntaxError);
+ EXPOSE(TypeError);
+ EXPOSE(URIError);
+
+ /* ** Numbers and Dates */
+ EXPOSE(Number);
+ EXPOSE(BigInt);
+ EXPOSE(Math);
EXPOSE(Date);
+
+ /* ** Text Processing */
+ EXPOSE(String);
EXPOSE(RegExp);
- EXPOSE(Math);
- EXPOSE(Function);
+
+ /* ** Indexed Collections */
+ EXPOSE(Array);
+ EXPOSE(Int8Array);
+ EXPOSE(Uint8Array);
+ EXPOSE(Uint8ClampedArray);
+ EXPOSE(Int16Array);
+ EXPOSE(Uint16Array);
+ EXPOSE(Int32Array);
+ EXPOSE(Uint32Array);
+ EXPOSE(Float32Array);
+ EXPOSE(Float64Array);
+ /* EXPOSE(BigInt64Array); */ /* Duktape lacks this - nonstandard API */
+ /* EXPOSE(BigUint64Array); */ /* Duktape lacks this - nonstandard API */
+
+ /* ** Keyed Collections */
+ /* EXPOSE(Map); */ /* Duktape lacks this - ES6 */
+ /* EXPOSE(Set); */ /* Duktape lacks this - ES6 */
+ /* EXPOSE(WeakMap); */ /* Duktape lacks this - ES6 */
+ /* EXPOSE(WeakSet); */ /* Duktape lacks this - ES6 */
+
+ /* Structured Data */
+ EXPOSE(ArrayBuffer);
+ /* EXPOSE(SharedArrayBuffer); */ /* Duktape lacks this - experimental API */
+ /* EXPOSE(Atomics); */ /* Duktape lacks this - experimental API */
+ EXPOSE(DataView);
+ EXPOSE(JSON);
+
+ /* ** Control abstraction properties */
+ /* EXPOSE(Promise); */ /* Probably ought to be one of ours? Also ES6 */
+ /* EXPOSE(Generator); */ /* Duktape and async? ES6 */
+ /* EXPOSE(GeneratorFunction); */ /* Duktape and async? ES6 */
+ /* EXPOSE(AsyncFunction); */ /* Duktape lacks this - experimental API */
+
+ /* Reflection */
+ EXPOSE(Reflect);
EXPOSE(Proxy);
- EXPOSE(String);
+
+ /* ** Internationalisation */
+ /* Duktape lacks Intl - Maybe polyfill it? */
+ /* There is suggestion that cdn.polyfill.io exists for it */
+
+ /* ** WebAssembly */
+ /* As yet, Duktape lacks WA */
#undef EXPOSE
+ /* Add s3kr1t method to close the compartment */
+ duk_dup(ctx, 0);
+ duk_push_string(ctx, MAGIC(closedownCompartment));
+ duk_push_c_function(ctx, dukky_window_closedown_compartment, DUK_VARARGS);
+ duk_def_prop(ctx, -3,
+ DUK_DEFPROP_HAVE_VALUE |
+ DUK_DEFPROP_HAVE_WRITABLE |
+ DUK_DEFPROP_HAVE_ENUMERABLE |
+ DUK_DEFPROP_ENUMERABLE |
+ DUK_DEFPROP_HAVE_CONFIGURABLE);
+ duk_pop(ctx);
%}
getter Window::document()
%{
- JS_LOG("priv=%p", priv);
+ NSLOG(netsurf, DEBUG, "priv=%p", priv);
dom_document *doc = priv->htmlc->document;
dukky_push_node(ctx, (struct dom_node *)doc);
return 1;
@@ -83,9 +405,11 @@ getter Window::console()
getter Window::location()
%{
+ /* obtain location object for this window (if it exists) */
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, MAGIC(Location));
if (duk_is_undefined(ctx, -1)) {
+ /* location object did not previously exist so create it */
duk_pop(ctx);
duk_push_pointer(ctx, llcache_handle_get_url(priv->htmlc->base.llcache));
@@ -137,8 +461,217 @@ setter Window::name()
method Window::alert()
%{
- duk_size_t msg_len;
- const char *msg = duk_safe_to_lstring(ctx, 0, &msg_len);
- NSLOG(netsurf, INFO, "JS ALERT: %*s", (int)msg_len, msg);
+ duk_idx_t dukky_argc = duk_get_top(ctx);
+ if (dukky_argc == 0) {
+ NSLOG(netsurf, INFO, "JS ALERT");
+ } else {
+ duk_size_t msg_len;
+ const char *msg;
+
+ if (!duk_is_string(ctx, 0)) {
+ duk_to_string(ctx, 0);
+ }
+ msg = duk_safe_to_lstring(ctx, 0, &msg_len);
+ NSLOG(netsurf, INFO, "JS ALERT: %*s", (int)msg_len, msg);
+ }
return 0;
%}
+
+method Window::setTimeout()
+%{
+ duk_idx_t argc = duk_get_top(ctx);
+ duk_int_t timeout = 10;
+ if (argc >= 2) {
+ timeout = duk_get_int(ctx, 1);
+ }
+ /* func, [timeout, args...] */
+ if (timeout < 10) { timeout = 10; }
+ size_t handle = window_alloc_new_callback(ctx, priv, false, (int)timeout);
+
+ duk_push_int(ctx, (duk_int_t)handle);
+ return 1;
+%}
+
+method Window::setInterval()
+%{
+ duk_idx_t argc = duk_get_top(ctx);
+ duk_int_t timeout = 10;
+ if (argc >= 2) {
+ timeout = duk_get_int(ctx, 1);
+ }
+ /* func, [timeout, args...] */
+ if (timeout < 10) { timeout = 10; }
+ size_t handle = window_alloc_new_callback(ctx, priv, true, (int)timeout);
+
+ duk_push_int(ctx, (duk_int_t)handle);
+ return 1;
+%}
+
+method Window::clearTimeout()
+%{
+ duk_int_t handle = duk_get_int(ctx, 0);
+ window_remove_callback_by_handle(ctx, priv, (size_t) handle);
+
+ return 0;
+%}
+
+method Window::clearInterval()
+%{
+ duk_int_t handle = duk_get_int(ctx, 0);
+ window_remove_callback_by_handle(ctx, priv, (size_t) handle);
+
+ return 0;
+%}
+
+getter Window::onabort();
+setter Window::onabort();
+getter Window::onafterprint();
+setter Window::onafterprint();
+getter Window::onautocompleteerror();
+setter Window::onautocompleteerror();
+getter Window::onautocomplete();
+setter Window::onautocomplete();
+getter Window::onbeforeprint();
+setter Window::onbeforeprint();
+getter Window::onbeforeunload();
+setter Window::onbeforeunload();
+getter Window::onblur();
+setter Window::onblur();
+getter Window::oncancel();
+setter Window::oncancel();
+getter Window::oncanplaythrough();
+setter Window::oncanplaythrough();
+getter Window::oncanplay();
+setter Window::oncanplay();
+getter Window::onchange();
+setter Window::onchange();
+getter Window::onclick();
+setter Window::onclick();
+getter Window::onclose();
+setter Window::onclose();
+getter Window::oncontextmenu();
+setter Window::oncontextmenu();
+getter Window::oncuechange();
+setter Window::oncuechange();
+getter Window::ondblclick();
+setter Window::ondblclick();
+getter Window::ondragend();
+setter Window::ondragend();
+getter Window::ondragenter();
+setter Window::ondragenter();
+getter Window::ondragexit();
+setter Window::ondragexit();
+getter Window::ondragleave();
+setter Window::ondragleave();
+getter Window::ondragover();
+setter Window::ondragover();
+getter Window::ondragstart();
+setter Window::ondragstart();
+getter Window::ondrag();
+setter Window::ondrag();
+getter Window::ondrop();
+setter Window::ondrop();
+getter Window::ondurationchange();
+setter Window::ondurationchange();
+getter Window::onemptied();
+setter Window::onemptied();
+getter Window::onended();
+setter Window::onended();
+getter Window::onerror();
+setter Window::onerror();
+getter Window::onfocus();
+setter Window::onfocus();
+getter Window::onhashchange();
+setter Window::onhashchange();
+getter Window::oninput();
+setter Window::oninput();
+getter Window::oninvalid();
+setter Window::oninvalid();
+getter Window::onkeydown();
+setter Window::onkeydown();
+getter Window::onkeypress();
+setter Window::onkeypress();
+getter Window::onkeyup();
+setter Window::onkeyup();
+getter Window::onlanguagechange();
+setter Window::onlanguagechange();
+getter Window::onloadeddata();
+setter Window::onloadeddata();
+getter Window::onloadedmetadata();
+setter Window::onloadedmetadata();
+getter Window::onloadstart();
+setter Window::onloadstart();
+getter Window::onload();
+setter Window::onload();
+getter Window::onmessage();
+setter Window::onmessage();
+getter Window::onmousedown();
+setter Window::onmousedown();
+getter Window::onmouseenter();
+setter Window::onmouseenter();
+getter Window::onmouseleave();
+setter Window::onmouseleave();
+getter Window::onmousemove();
+setter Window::onmousemove();
+getter Window::onmouseout();
+setter Window::onmouseout();
+getter Window::onmouseover();
+setter Window::onmouseover();
+getter Window::onmouseup();
+setter Window::onmouseup();
+getter Window::onoffline();
+setter Window::onoffline();
+getter Window::ononline();
+setter Window::ononline();
+getter Window::onpagehide();
+setter Window::onpagehide();
+getter Window::onpageshow();
+setter Window::onpageshow();
+getter Window::onpause();
+setter Window::onpause();
+getter Window::onplaying();
+setter Window::onplaying();
+getter Window::onplay();
+setter Window::onplay();
+getter Window::onpopstate();
+setter Window::onpopstate();
+getter Window::onprogress();
+setter Window::onprogress();
+getter Window::onratechange();
+setter Window::onratechange();
+getter Window::onreset();
+setter Window::onreset();
+getter Window::onresize();
+setter Window::onresize();
+getter Window::onscroll();
+setter Window::onscroll();
+getter Window::onseeked();
+setter Window::onseeked();
+getter Window::onseeking();
+setter Window::onseeking();
+getter Window::onselect();
+setter Window::onselect();
+getter Window::onshow();
+setter Window::onshow();
+getter Window::onsort();
+setter Window::onsort();
+getter Window::onstalled();
+setter Window::onstalled();
+getter Window::onstorage();
+setter Window::onstorage();
+getter Window::onsubmit();
+setter Window::onsubmit();
+getter Window::onsuspend();
+setter Window::onsuspend();
+getter Window::ontimeupdate();
+setter Window::ontimeupdate();
+getter Window::ontoggle();
+setter Window::ontoggle();
+getter Window::onunload();
+setter Window::onunload();
+getter Window::onvolumechange();
+setter Window::onvolumechange();
+getter Window::onwaiting();
+setter Window::onwaiting();
+getter Window::onwheel();
+setter Window::onwheel();
diff --git a/content/handlers/javascript/duktape/duk_config.h b/content/handlers/javascript/duktape/duk_config.h
index 40df0fe..0caed88 100644
--- a/content/handlers/javascript/duktape/duk_config.h
+++ b/content/handlers/javascript/duktape/duk_config.h
@@ -18,6 +18,7 @@
* - QNX
* - TI-Nspire
* - Emscripten
+ * - Android
* - Linux
* - Solaris
* - AIX
@@ -170,6 +171,10 @@
#define DUK_F_BCC
#endif
+#if defined(ANDROID) || defined(__ANDROID__)
+#define DUK_F_ANDROID
+#endif
+
/* Linux */
#if defined(__linux) || defined(__linux__) || defined(linux)
#define DUK_F_LINUX
@@ -246,9 +251,9 @@
#endif
/* ARM */
-#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(__aarch64__)
+#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__)
#define DUK_F_ARM
-#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__)
+#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)
#define DUK_F_ARM64
#else
#define DUK_F_ARM32
@@ -356,10 +361,6 @@
#define DUK_F_VBCC
#endif
-#if defined(ANDROID) || defined(__ANDROID__)
-#define DUK_F_ANDROID
-#endif
-
/* Atari Mint */
#if defined(__MINT__)
#define DUK_F_MINT
@@ -665,6 +666,41 @@
#define DUK_USE_DATE_FMT_STRFTIME
#define DUK_USE_OS_STRING "emscripten"
+#elif defined(DUK_F_ANDROID)
+/* --- Android --- */
+#if defined(DUK_COMPILING_DUKTAPE)
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200809L
+#endif
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE /* e.g. getdate_r */
+#endif
+#if !defined(_XOPEN_SOURCE)
+#define _XOPEN_SOURCE /* e.g. strptime */
+#endif
+#endif /* DUK_COMPILING_DUKTAPE */
+
+#include <sys/types.h>
+#if defined(DUK_F_BCC)
+/* no endian.h or stdint.h */
+#else
+#include <endian.h>
+#include <stdint.h>
+#endif /* DUK_F_BCC */
+#include <sys/param.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define DUK_USE_DATE_NOW_GETTIMEOFDAY
+#define DUK_USE_DATE_TZO_GMTIME_R
+#define DUK_USE_DATE_PRS_STRPTIME
+#define DUK_USE_DATE_FMT_STRFTIME
+
+#if 0 /* XXX: safe condition? */
+#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME
+#endif
+
+#define DUK_USE_OS_STRING "android"
#elif defined(DUK_F_LINUX)
/* --- Linux --- */
#if defined(DUK_COMPILING_DUKTAPE)
@@ -1069,6 +1105,18 @@
#undef DUK_USE_GCC_PRAGMAS
#define DUK_USE_PACK_CLANG_ATTR
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap64)
+#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))
+#endif
+#if __has_builtin(__builtin_bswap32)
+#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))
+#endif
+#if __has_builtin(__builtin_bswap16)
+#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))
+#endif
+#endif
#elif defined(DUK_F_GCC)
/* --- GCC --- */
#if defined(DUK_F_C99) || defined(DUK_F_CPP11)
@@ -1079,13 +1127,17 @@
#define DUK_VA_COPY(dest,src) __va_copy(dest,src)
#endif
-#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L)
-/* since gcc-2.5 */
+#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && (DUK_F_GCC_VERSION < 50000L)
+/* Since gcc-2.5.
+ *
+ * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related
+ * issue: https://github.com/svaarala/duktape/issues/2155.
+ */
#define DUK_NORETURN(decl) decl __attribute__((noreturn))
#endif
#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)
-/* since gcc-4.5 */
+/* Since gcc-4.5. */
#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while (0)
#endif
@@ -1198,6 +1250,16 @@
#endif
#define DUK_USE_PACK_GCC_ATTR
+
+/* Availability varies based on platform (between GCC 4.4 and 4.8), and there
+ * are apparently some bugs in GCC 4.x. Check for GCC 5.0 before enabling
+ * these to be safe.
+ */
+#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 50000L)
+#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))
+#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))
+#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))
+#endif
#elif defined(DUK_F_MSVC)
/* --- MSVC --- */
/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */
@@ -2504,7 +2566,7 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_ALIGN_BY 8
#endif
-/* Compiler specific hackery needed to force struct size to match aligment,
+/* Compiler specific hackery needed to force struct size to match alignment,
* see e.g. duk_hbuffer.h.
*
* http://stackoverflow.com/questions/11130109/c-struct-size-alignment
@@ -2515,6 +2577,13 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_PACK_DUMMY_MEMBER
#endif
+#if !defined(DUK_U64_CONSTANT)
+#define DUK_U64_CONSTANT(x) x##ULL
+#endif
+#if !defined(DUK_I64_CONSTANT)
+#define DUK_I64_CONSTANT(x) x##LL
+#endif
+
#if !defined(DUK_VA_COPY)
/* We need va_copy() which is defined in C99 / C++11, so an awkward
* replacement is needed for pre-C99 / pre-C++11 environments. This
@@ -2665,17 +2734,30 @@ typedef struct duk_hthread duk_context;
#endif
#endif
+#if defined(DUK_F_HAVE_64BIT)
+#if !defined(DUK_BSWAP64)
+#define DUK_BSWAP64(x) \
+ ((((duk_uint64_t) (x)) >> 56U) | \
+ ((((duk_uint64_t) (x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \
+ ((((duk_uint64_t) (x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \
+ ((((duk_uint64_t) (x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \
+ ((((duk_uint64_t) (x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \
+ ((((duk_uint64_t) (x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \
+ ((((duk_uint64_t) (x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \
+ (((duk_uint64_t) (x)) << 56U))
+#endif
+#endif
#if !defined(DUK_BSWAP32)
#define DUK_BSWAP32(x) \
- ((((duk_uint32_t) (x)) >> 24) | \
- ((((duk_uint32_t) (x)) >> 8) & 0xff00UL) | \
- ((((duk_uint32_t) (x)) << 8) & 0xff0000UL) | \
- (((duk_uint32_t) (x)) << 24))
+ ((((duk_uint32_t) (x)) >> 24U) | \
+ ((((duk_uint32_t) (x)) >> 8U) & 0xff00UL) | \
+ ((((duk_uint32_t) (x)) << 8U) & 0xff0000UL) | \
+ (((duk_uint32_t) (x)) << 24U))
#endif
#if !defined(DUK_BSWAP16)
#define DUK_BSWAP16(x) \
- ((duk_uint16_t) (x) >> 8) | \
- ((duk_uint16_t) (x) << 8)
+ ((duk_uint16_t) (x) >> 8U) | \
+ ((duk_uint16_t) (x) << 8U)
#endif
/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */
@@ -2698,13 +2780,6 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_GCC_PRAGMAS
#endif
-#if !defined(DUK_U64_CONSTANT)
-#define DUK_U64_CONSTANT(x) x##ULL
-#endif
-#if !defined(DUK_I64_CONSTANT)
-#define DUK_I64_CONSTANT(x) x##LL
-#endif
-
/* Workaround for GH-323: avoid inlining control when compiling from
* multiple sources, as it causes compiler portability trouble.
*/
@@ -2807,7 +2882,6 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_CACHE_ACTIVATION
#define DUK_USE_CACHE_CATCHER
#define DUK_USE_CALLSTACK_LIMIT 10000
-#define DUK_USE_COMMONJS_MODULES
#define DUK_USE_COMPILER_RECLIMIT 2500
#define DUK_USE_COROUTINE_SUPPORT
#undef DUK_USE_CPP_EXCEPTIONS
@@ -2912,6 +2986,7 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256
#define DUK_USE_MATH_BUILTIN
#define DUK_USE_NATIVE_CALL_RECLIMIT 1000
+#undef DUK_USE_NATIVE_STACK_CHECK
#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT
#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY
@@ -2962,12 +3037,11 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_STRTAB_RESIZE_CHECK_MASK 255
#define DUK_USE_STRTAB_SHRINK_LIMIT 6
#undef DUK_USE_STRTAB_TORTURE
-#undef DUK_USE_SYMBOL_BUILTIN
+#define DUK_USE_SYMBOL_BUILTIN
#define DUK_USE_TAILCALL
#define DUK_USE_TARGET_INFO "unknown"
#define DUK_USE_TRACEBACKS
#define DUK_USE_TRACEBACK_DEPTH 10
-#define DUK_USE_USER_DECLARE() /* no user declarations */
#define DUK_USE_VALSTACK_GROW_SHIFT 2
#define DUK_USE_VALSTACK_LIMIT 1000000L
#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2
diff --git a/content/handlers/javascript/duktape/duk_custom.h b/content/handlers/javascript/duktape/duk_custom.h
index 2ff9317..b373719 100644
--- a/content/handlers/javascript/duktape/duk_custom.h
+++ b/content/handlers/javascript/duktape/duk_custom.h
@@ -36,3 +36,5 @@
extern duk_bool_t dukky_check_timeout(void *udata);
#define DUK_USE_EXEC_TIMEOUT_CHECK dukky_check_timeout
+
+#include "netsurf/inttypes.h"
diff --git a/content/handlers/javascript/duktape/dukky.c b/content/handlers/javascript/duktape/dukky.c
index 8cfeb39..5980b2b 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -19,7 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* Duktapeish implementation of javascript engine functions.
*/
@@ -37,6 +38,8 @@
#include "javascript/content.h"
#include "duktape/binding.h"
+#include "duktape/generics.js.inc"
+#include "duktape/polyfill.js.inc"
#include "duktape.h"
#include "dukky.h"
@@ -47,6 +50,16 @@
#define HANDLER_LISTENER_MAGIC MAGIC(HANDLER_LISTENER_MAP)
#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
#define EVENT_LISTENER_JS_MAGIC MAGIC(EVENT_LISTENER_JS_MAP)
+#define GENERICS_MAGIC MAGIC(GENERICS_TABLE)
+
+/**
+ * dukky javascript context
+ */
+struct jscontext {
+ duk_context *ctx; /**< duktape base context */
+ duk_context *thread; /**< duktape compartment */
+ uint64_t exec_start_time;
+};
static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
{
@@ -56,17 +69,20 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
/* ... obj args protoname */
duk_get_global_string(ctx, PROTO_MAGIC);
/* .. obj args protoname prototab */
- duk_insert(ctx, -2);
- /* ... obj args prototab protoname */
+ duk_dup(ctx, -2);
+ /* ... obj args protoname prototab protoname */
duk_get_prop(ctx, -2);
- /* ... obj args prototab {proto/undefined} */
+ /* ... obj args protoname prototab {proto/undefined} */
if (duk_is_undefined(ctx, -1)) {
- NSLOG(netsurf, INFO,
- "RuhRoh, couldn't find a prototype, HTMLUnknownElement it is");
+ NSLOG(dukky, WARNING,
+ "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement",
+ duk_get_string(ctx, -3) + 2 /* Skip the two unprintables */);
duk_pop(ctx);
duk_push_string(ctx, PROTO_NAME(HTMLUNKNOWNELEMENT));
duk_get_prop(ctx, -2);
}
+ /* ... obj args protoname prototab proto */
+ duk_remove(ctx, -3);
/* ... obj args prototab proto */
duk_dup(ctx, -1);
/* ... obj args prototab proto proto */
@@ -78,7 +94,7 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
/* ... initfn obj[proto] args prototab proto */
duk_pop_2(ctx);
/* ... initfn obj[proto] args */
- NSLOG(netsurf, INFO, "Call the init function");
+ NSLOG(dukky, DEEPDEBUG, "Call the init function");
duk_call(ctx, nargs + 1);
return 1; /* The object */
}
@@ -86,7 +102,7 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args)
{
duk_ret_t ret;
- NSLOG(netsurf, INFO, "name=%s nargs=%d", name + 2, args);
+ NSLOG(dukky, DEEPDEBUG, "name=%s nargs=%d", name + 2, args);
/* ... args */
duk_push_object(ctx);
/* ... args obj */
@@ -107,7 +123,7 @@ duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args)
if ((ret = duk_safe_call(ctx, dukky_populate_object, NULL, args + 3, 1))
!= DUK_EXEC_SUCCESS)
return ret;
- NSLOG(netsurf, INFO, "created");
+ NSLOG(dukky, DEEPDEBUG, "created");
return DUK_EXEC_SUCCESS;
}
@@ -147,7 +163,7 @@ dukky_push_node_stacked(duk_context *ctx)
if (duk_safe_call(ctx, dukky_populate_object, NULL, 4, 1)
!= DUK_EXEC_SUCCESS) {
duk_set_top(ctx, top_at_fail);
- NSLOG(netsurf, INFO, "Boo and also hiss");
+ NSLOG(dukky, ERROR, "Failed to populate object prototype");
return false;
}
/* ... nodeptr klass nodes node */
@@ -163,6 +179,12 @@ dukky_push_node_stacked(duk_context *ctx)
/* ... node nodeptr klass nodes */
duk_pop_3(ctx);
/* ... node */
+ {
+ duk_dup(ctx, -1);
+ const char * what = duk_safe_to_string(ctx, -1);
+ NSLOG(dukky, DEEPDEBUG, "Created: %s", what);
+ duk_pop(ctx);
+ }
return true;
}
@@ -205,7 +227,7 @@ static void dukky_html_element_class_from_tag_type(dom_html_element_type type,
SET_HTML_CLASS(LINK)
break;
case DOM_HTML_ELEMENT_TYPE_BUTTON:
- SET_HTML_CLASS(BUTTOM)
+ SET_HTML_CLASS(BUTTON)
break;
case DOM_HTML_ELEMENT_TYPE_INPUT:
SET_HTML_CLASS(INPUT)
@@ -385,14 +407,14 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
err = dom_node_get_namespace(node, &namespace);
if (err != DOM_NO_ERR) {
/* Feck it, element */
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, ERROR,
"dom_node_get_namespace() failed");
duk_push_string(ctx, PROTO_NAME(ELEMENT));
break;
}
if (namespace == NULL) {
/* No namespace, -> element */
- NSLOG(netsurf, INFO, "no namespace");
+ NSLOG(dukky, DEBUG, "no namespace");
duk_push_string(ctx, PROTO_NAME(ELEMENT));
break;
}
@@ -442,7 +464,7 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
duk_bool_t
dukky_push_node(duk_context *ctx, struct dom_node *node)
{
- JS_LOG("Pushing node %p", node);
+ NSLOG(dukky, DEEPDEBUG, "Pushing node %p", node);
/* First check if we can find the node */
/* ... */
duk_get_global_string(ctx, NODE_MAGIC);
@@ -457,7 +479,12 @@ dukky_push_node(duk_context *ctx, struct dom_node *node)
/* ... node nodes */
duk_pop(ctx);
/* ... node */
- JS_LOG("Found it memoised");
+ {
+ duk_dup(ctx, -1);
+ const char * what = duk_safe_to_string(ctx, -1);
+ NSLOG(dukky, DEEPDEBUG, "Found it memoised: %s", what);
+ duk_pop(ctx);
+ }
return true;
}
/* ... nodes undefined */
@@ -522,6 +549,7 @@ static void *dukky_realloc_function(void *udata, void *ptr, duk_size_t size)
return realloc(ptr, size);
}
+
static void dukky_free_function(void *udata, void *ptr)
{
if (ptr != NULL)
@@ -529,15 +557,36 @@ static void dukky_free_function(void *udata, void *ptr)
}
-/**************************************** js.h ******************************/
-struct jscontext {
- duk_context *ctx;
- duk_context *thread;
- uint64_t exec_start_time;
-};
-
#define CTX (ctx->thread)
+/**
+ * close current compartment
+ *
+ * \param ctx javascript context
+ * \return NSERROR_OK on sucess.
+ */
+static nserror dukky_closecompartment(jscontext *ctx)
+{
+ /* ensure there is an active compartment */
+ if (ctx->thread == NULL) {
+ return NSERROR_OK;
+ }
+
+ /* Closing down the extant compartment */
+ NSLOG(dukky, DEEPDEBUG, "Closing down extant compartment...");
+ duk_get_global_string(ctx->thread, MAGIC(closedownCompartment));
+ dukky_pcall(CTX, 0, true);
+ NSLOG(dukky, DEEPDEBUG, "Popping the thread off the stack");
+ duk_set_top(ctx->ctx, 0);
+ duk_gc(ctx->ctx, 0);
+ duk_gc(ctx->ctx, DUK_GC_COMPACT);
+
+ ctx->thread = NULL;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in js.h */
void js_initialise(void)
{
/** TODO: Forces JS on for our testing, needs changing before a release
@@ -549,21 +598,22 @@ void js_initialise(void)
javascript_init();
}
+
+/* exported interface documented in js.h */
void js_finalise(void)
{
/* NADA for now */
}
-#define DUKKY_NEW_PROTOTYPE(klass, uklass, klass_name) \
- dukky_create_prototype(ctx, dukky_##klass##___proto, PROTO_NAME(uklass), klass_name)
-nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
- jscontext **jsctx)
+/* exported interface documented in js.h */
+nserror
+js_newcontext(int timeout, jscallback *cb, void *cbctx, jscontext **jsctx)
{
duk_context *ctx;
jscontext *ret = calloc(1, sizeof(*ret));
*jsctx = NULL;
- NSLOG(netsurf, INFO, "Creating new duktape javascript context");
+ NSLOG(dukky, DEBUG, "Creating new duktape javascript context");
if (ret == NULL) return NSERROR_NOMEM;
ctx = ret->ctx = duk_create_heap(
dukky_alloc_function,
@@ -584,21 +634,29 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
return NSERROR_OK;
}
+
+/* exported interface documented in js.h */
void js_destroycontext(jscontext *ctx)
{
- NSLOG(netsurf, INFO, "Destroying duktape javascript context");
+ NSLOG(dukky, DEBUG, "Destroying duktape javascript context");
+ dukky_closecompartment(ctx);
duk_destroy_heap(ctx->ctx);
free(ctx);
}
+
+/* exported interface documented in js.h */
jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
{
assert(ctx != NULL);
+ NSLOG(dukky, DEBUG,
+ "New javascript/duktape compartment, win_priv=%p, doc_priv=%p",
+ win_priv, doc_priv);
+
/* Pop any active thread off */
- NSLOG(netsurf, INFO,
- "Yay, new compartment, win_priv=%p, doc_priv=%p", win_priv,
- doc_priv);
- duk_set_top(ctx->ctx, 0);
+ dukky_closecompartment(ctx);
+
+ /* create new compartment thread */
duk_push_thread(ctx->ctx);
ctx->thread = duk_require_context(ctx->ctx, -1);
duk_push_int(CTX, 0);
@@ -624,13 +682,56 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
duk_push_object(CTX);
duk_put_global_string(CTX, EVENT_MAGIC);
- return (jsobject *)ctx;
-}
+ /* Now load the polyfills */
+ /* ... */
+ duk_push_string(CTX, "polyfill.js");
+ /* ..., polyfill.js */
+ if (duk_pcompile_lstring_filename(CTX, DUK_COMPILE_EVAL,
+ (const char *)polyfill_js, polyfill_js_len) != 0) {
+ NSLOG(dukky, CRITICAL, "%s", duk_safe_to_string(CTX, -1));
+ NSLOG(dukky, CRITICAL, "Unable to compile polyfill.js, compartment aborted");
+ return NULL;
+ }
+ /* ..., (generics.js) */
+ if (dukky_pcall(CTX, 0, true) != 0) {
+ NSLOG(dukky, CRITICAL, "Unable to run polyfill.js, compartment aborted");
+ return NULL;
+ }
+ /* ..., result */
+ duk_pop(CTX);
+ /* ... */
-static duk_ret_t eval_top_string(duk_context *ctx, void *udata)
-{
- duk_eval(ctx);
- return 0;
+ /* Now load the NetSurf table in */
+ /* ... */
+ duk_push_string(CTX, "generics.js");
+ /* ..., generics.js */
+ if (duk_pcompile_lstring_filename(CTX, DUK_COMPILE_EVAL,
+ (const char *)generics_js, generics_js_len) != 0) {
+ NSLOG(dukky, CRITICAL, "%s", duk_safe_to_string(CTX, -1));
+ NSLOG(dukky, CRITICAL, "Unable to compile generics.js, compartment aborted");
+ return NULL;
+ }
+ /* ..., (generics.js) */
+ if (dukky_pcall(CTX, 0, true) != 0) {
+ NSLOG(dukky, CRITICAL, "Unable to run generics.js, compartment aborted");
+ return NULL;
+ }
+ /* ..., result */
+ duk_pop(CTX);
+ /* ... */
+ duk_push_global_object(CTX);
+ /* ..., Win */
+ duk_get_prop_string(CTX, -1, "NetSurf");
+ /* ..., Win, NetSurf */
+ duk_put_global_string(CTX, GENERICS_MAGIC);
+ /* ..., Win */
+ duk_del_prop_string(CTX, -1, "NetSurf");
+ duk_pop(CTX);
+ /* ... */
+
+ dukky_log_stack_frame(CTX, "New compartment created");
+
+ return (jsobject *)ctx;
}
duk_bool_t dukky_check_timeout(void *udata)
@@ -649,37 +750,111 @@ duk_bool_t dukky_check_timeout(void *udata)
now > (ctx->exec_start_time + JS_EXEC_TIMEOUT_MS);
}
-bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
+static void dukky_dump_error(duk_context *ctx)
+{
+ /* stack is ..., errobj */
+ duk_dup_top(ctx);
+ /* ..., errobj, errobj */
+ NSLOG(jserrors, WARNING, "Uncaught error in JS: %s", duk_safe_to_stacktrace(ctx, -1));
+ /* ..., errobj, errobj.stackstring */
+ duk_pop(ctx);
+ /* ..., errobj */
+}
+
+duk_int_t dukky_pcall(duk_context *ctx, duk_size_t argc, bool reset_timeout)
+{
+ if (reset_timeout) {
+ duk_memory_functions funcs;
+ jscontext *jsctx;
+ duk_get_memory_functions(ctx, &funcs);
+ jsctx = funcs.udata;
+ (void) nsu_getmonotonic_ms(&jsctx->exec_start_time);
+ }
+
+ duk_int_t ret = duk_pcall(ctx, argc);
+ if (ret) {
+ /* Something went wrong calling this... */
+ dukky_dump_error(ctx);
+ }
+
+ return ret;
+}
+
+
+void dukky_push_generics(duk_context *ctx, const char *generic)
+{
+ /* ... */
+ duk_get_global_string(ctx, GENERICS_MAGIC);
+ /* ..., generics */
+ duk_get_prop_string(ctx, -1, generic);
+ /* ..., generics, generic */
+ duk_remove(ctx, -2);
+ /* ..., generic */
+}
+
+static duk_int_t dukky_push_context_dump(duk_context *ctx, void *udata)
+{
+ duk_push_context_dump(ctx);
+ return 1;
+}
+
+void dukky_log_stack_frame(duk_context *ctx, const char * reason)
+{
+ if (duk_safe_call(ctx, dukky_push_context_dump, NULL, 0, 1) != 0) {
+ duk_pop(ctx);
+ duk_push_string(ctx, "[???]");
+ }
+ NSLOG(dukky, DEEPDEBUG, "%s, stack is: %s", reason, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+}
+
+
+/* exported interface documented in js.h */
+bool
+js_exec(jscontext *ctx, const uint8_t *txt, size_t txtlen, const char *name)
{
assert(ctx);
- if (txt == NULL || txtlen == 0) return false;
+
+ if (txt == NULL || txtlen == 0) {
+ return false;
+ }
+
duk_set_top(CTX, 0);
- duk_push_lstring(CTX, txt, txtlen);
+ NSLOG(dukky, DEEPDEBUG, "Running %"PRIsizet" bytes from %s", txtlen, name);
+ /* NSLOG(dukky, DEEPDEBUG, "\n%s\n", txt); */
(void) nsu_getmonotonic_ms(&ctx->exec_start_time);
- if (duk_safe_call(CTX, eval_top_string, NULL, 1, 1) == DUK_EXEC_ERROR) {
- duk_get_prop_string(CTX, 0, "name");
- duk_get_prop_string(CTX, 0, "message");
- duk_get_prop_string(CTX, 0, "fileName");
- duk_get_prop_string(CTX, 0, "lineNumber");
- duk_get_prop_string(CTX, 0, "stack");
- NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
- duk_safe_to_string(CTX, 1), duk_safe_to_string(CTX, 2));
- NSLOG(netsurf, INFO, " was at: %s line %s",
- duk_safe_to_string(CTX, 3), duk_safe_to_string(CTX, 4));
- NSLOG(netsurf, INFO, " Stack trace: %s",
- duk_safe_to_string(CTX, 5));
- return false;
+ if (name != NULL) {
+ duk_push_string(CTX, name);
+ } else {
+ duk_push_string(CTX, "?unknown source?");
+ }
+ if (duk_pcompile_lstring_filename(CTX,
+ DUK_COMPILE_EVAL,
+ (const char *)txt,
+ txtlen) != 0) {
+ NSLOG(dukky, DEBUG, "Failed to compile JavaScript input");
+ goto handle_error;
}
+
+ if (duk_pcall(CTX, 0/*nargs*/) == DUK_EXEC_ERROR) {
+ NSLOG(dukky, DEBUG, "Failed to execute JavaScript");
+ goto handle_error;
+ }
+
if (duk_get_top(CTX) == 0) duk_push_boolean(CTX, false);
- NSLOG(netsurf, INFO, "Returning %s",
+ NSLOG(dukky, DEEPDEBUG, "Returning %s",
duk_get_boolean(CTX, 0) ? "true" : "false");
return duk_get_boolean(CTX, 0);
+
+handle_error:
+ dukky_dump_error(CTX);
+ return false;
}
/*** New style event handling ***/
-static void dukky_push_event(duk_context *ctx, dom_event *evt)
+void dukky_push_event(duk_context *ctx, dom_event *evt)
{
/* ... */
duk_get_global_string(ctx, EVENT_MAGIC);
@@ -721,9 +896,18 @@ static void dukky_push_handler_code_(duk_context *ctx, dom_string *name,
dom_exception exc;
dom_node_type ntype;
- /* Currently safe since libdom has no event targets which are not
- * nodes. Reconsider this as and when we work out how to have
- * window do stuff
+ /* If et is NULL, then we're actually dealing with the Window object
+ * which has no default handlers and no way to assign handlers
+ * which aren't directly stored in the HANDLER_MAGIC
+ */
+ if (et == NULL) {
+ duk_push_lstring(ctx, "", 0);
+ return;
+ }
+
+ /* The rest of this assumes et is a proper event target and expands
+ * out from there based on the assumption that all valid event targets
+ * are nodes.
*/
exc = dom_node_get_node_type(et, &ntype);
if (exc != DOM_NO_ERR) {
@@ -788,7 +972,7 @@ bool dukky_get_current_value_of_event_handler(duk_context *ctx,
/* ... node fullhandlersrc filename */
if (duk_pcompile(ctx, DUK_COMPILE_FUNCTION) != 0) {
/* ... node err */
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"Unable to proceed with handler, could not compile");
duk_pop_2(ctx);
return false;
@@ -823,27 +1007,27 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
duk_get_memory_functions(ctx, &funcs);
jsctx = funcs.udata;
- NSLOG(netsurf, INFO, "WOOP WOOP, An event:");
+ NSLOG(dukky, DEBUG, "Handling an event in duktape interface...");
exc = dom_event_get_type(evt, &name);
if (exc != DOM_NO_ERR) {
- NSLOG(netsurf, INFO, "Unable to find the event name");
+ NSLOG(dukky, DEBUG, "Unable to find the event name");
return;
}
- NSLOG(netsurf, INFO, "Event's name is %*s", dom_string_length(name),
+ NSLOG(dukky, DEBUG, "Event's name is %*s", dom_string_length(name),
dom_string_data(name));
exc = dom_event_get_event_phase(evt, &phase);
if (exc != DOM_NO_ERR) {
- NSLOG(netsurf, INFO, "Unable to get event phase");
+ NSLOG(dukky, WARNING, "Unable to get event phase");
return;
}
- NSLOG(netsurf, INFO, "Event phase is: %s (%d)",
+ NSLOG(dukky, DEBUG, "Event phase is: %s (%d)",
phase == DOM_CAPTURING_PHASE ? "capturing" : phase == DOM_AT_TARGET ? "at-target" : phase == DOM_BUBBLING_PHASE ? "bubbling" : "unknown",
(int)phase);
exc = dom_event_get_current_target(evt, &targ);
if (exc != DOM_NO_ERR) {
dom_string_unref(name);
- NSLOG(netsurf, INFO, "Unable to find the event target");
+ NSLOG(dukky, DEBUG, "Unable to find the event target");
return;
}
@@ -857,7 +1041,7 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
if (dukky_push_node(ctx, (dom_node *)targ) == false) {
dom_string_unref(name);
dom_node_unref(targ);
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"Unable to push JS node representation?!");
return;
}
@@ -874,11 +1058,11 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... err */
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"OH NOES! An error running a callback. Meh.");
exc = dom_event_stop_immediate_propagation(evt);
if (exc != DOM_NO_ERR)
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"WORSE! could not stop propagation");
duk_get_prop_string(ctx, -1, "name");
duk_get_prop_string(ctx, -2, "message");
@@ -886,13 +1070,13 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
duk_get_prop_string(ctx, -4, "lineNumber");
duk_get_prop_string(ctx, -5, "stack");
/* ... err name message fileName lineNumber stack */
- NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",
duk_safe_to_string(ctx, -5),
duk_safe_to_string(ctx, -4));
- NSLOG(netsurf, INFO, " was at: %s line %s",
+ NSLOG(dukky, INFO, " was at: %s line %s",
duk_safe_to_string(ctx, -3),
duk_safe_to_string(ctx, -2));
- NSLOG(netsurf, INFO, " Stack trace: %s",
+ NSLOG(dukky, INFO, " Stack trace: %s",
duk_safe_to_string(ctx, -1));
duk_pop_n(ctx, 6);
@@ -973,11 +1157,11 @@ handle_extras:
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... copy handler err */
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"OH NOES! An error running a callback. Meh.");
exc = dom_event_stop_immediate_propagation(evt);
if (exc != DOM_NO_ERR)
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"WORSE! could not stop propagation");
duk_get_prop_string(ctx, -1, "name");
duk_get_prop_string(ctx, -2, "message");
@@ -985,14 +1169,14 @@ handle_extras:
duk_get_prop_string(ctx, -4, "lineNumber");
duk_get_prop_string(ctx, -5, "stack");
/* ... err name message fileName lineNumber stack */
- NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",
duk_safe_to_string(ctx, -5),
duk_safe_to_string(ctx, -4));
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
" was at: %s line %s",
duk_safe_to_string(ctx, -3),
duk_safe_to_string(ctx, -2));
- NSLOG(netsurf, INFO, " Stack trace: %s",
+ NSLOG(dukky, DEBUG, " Stack trace: %s",
duk_safe_to_string(ctx, -1));
duk_pop_n(ctx, 7);
@@ -1023,8 +1207,14 @@ void dukky_register_event_listener_for(duk_context *ctx,
dom_exception exc;
/* ... */
- if (dukky_push_node(ctx, (struct dom_node *)ele) == false)
- return;
+ if (ele == NULL) {
+ /* A null element is the Window object */
+ duk_push_global_object(ctx);
+ } else {
+ /* Non null elements must be pushed as a node object */
+ if (dukky_push_node(ctx, (struct dom_node *)ele) == false)
+ return;
+ }
/* ... node */
duk_get_prop_string(ctx, -1, HANDLER_LISTENER_MAGIC);
/* ... node handlers */
@@ -1045,17 +1235,25 @@ void dukky_register_event_listener_for(duk_context *ctx,
/* ... node handlers */
duk_pop_2(ctx);
/* ... */
+ if (ele == NULL) {
+ /* Nothing more to do, Window doesn't register in the
+ * normal event listener flow
+ */
+ return;
+ }
+
+ /* Otherwise add an event listener to the element */
exc = dom_event_listener_create(dukky_generic_event_handler, ctx,
&listen);
if (exc != DOM_NO_ERR) return;
exc = dom_event_target_add_event_listener(
ele, name, listen, capture);
if (exc != DOM_NO_ERR) {
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"Unable to register listener for %p.%*s", ele,
dom_string_length(name), dom_string_data(name));
} else {
- NSLOG(netsurf, INFO, "have registered listener for %p.%*s",
+ NSLOG(dukky, DEBUG, "have registered listener for %p.%*s",
ele, dom_string_length(name), dom_string_data(name));
}
dom_event_listener_unref(listen);
@@ -1223,7 +1421,7 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
dom_event *evt;
dom_event_target *body;
- NSLOG(netsurf, INFO, "Event: %s (doc=%p, target=%p)", type, doc,
+ NSLOG(dukky, DEBUG, "Event: %s (doc=%p, target=%p)", type, doc,
target);
/** @todo Make this more generic, this only handles load and only
@@ -1275,10 +1473,14 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
/* ... handlers bodynode */
if (dukky_get_current_value_of_event_handler(
CTX, corestring_dom_load, body) == false) {
+ /* Unref the body, we don't need it any more */
+ dom_node_unref(body);
/* ... handlers */
duk_pop(CTX);
return true;
}
+ /* Unref the body, we don't need it any more */
+ dom_node_unref(body);
/* ... handlers handler bodynode */
duk_pop(CTX);
}
@@ -1295,7 +1497,7 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
if (duk_pcall_method(CTX, 1) != 0) {
/* Failed to run the handler */
/* ... err */
- NSLOG(netsurf, INFO,
+ NSLOG(dukky, DEBUG,
"OH NOES! An error running a handler. Meh.");
duk_get_prop_string(CTX, -1, "name");
duk_get_prop_string(CTX, -2, "message");
@@ -1303,13 +1505,13 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
duk_get_prop_string(CTX, -4, "lineNumber");
duk_get_prop_string(CTX, -5, "stack");
/* ... err name message fileName lineNumber stack */
- NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",
duk_safe_to_string(CTX, -5),
duk_safe_to_string(CTX, -4));
- NSLOG(netsurf, INFO, " was at: %s line %s",
+ NSLOG(dukky, DEBUG, " was at: %s line %s",
duk_safe_to_string(CTX, -3),
duk_safe_to_string(CTX, -2));
- NSLOG(netsurf, INFO, " Stack trace: %s",
+ NSLOG(dukky, DEBUG, " Stack trace: %s",
duk_safe_to_string(CTX, -1));
duk_pop_n(CTX, 6);
diff --git a/content/handlers/javascript/duktape/dukky.h b/content/handlers/javascript/duktape/dukky.h
index 435e0c3..5a67951 100644
--- a/content/handlers/javascript/duktape/dukky.h
+++ b/content/handlers/javascript/duktape/dukky.h
@@ -25,14 +25,6 @@
#ifndef DUKKY_H
#define DUKKY_H
-#ifdef JS_DEBUG
-# define JS_LOG(format, args...) NSLOG(netsurf, INFO, format , ##args)
-#else
-# define JS_LOG(format, ...) ((void) 0)
-#endif
-
-#define LOG(format, args...) NSLOG(netsurf, INFO, format , ##args)
-
duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args);
duk_bool_t dukky_push_node_stacked(duk_context *ctx);
duk_bool_t dukky_push_node(duk_context *ctx, struct dom_node *node);
@@ -44,6 +36,7 @@ void dukky_register_event_listener_for(duk_context *ctx,
bool dukky_get_current_value_of_event_handler(duk_context *ctx,
dom_string *name,
dom_event_target *et);
+void dukky_push_event(duk_context *ctx, dom_event *evt);
bool dukky_event_target_push_listeners(duk_context *ctx, bool dont_create);
typedef enum {
@@ -55,4 +48,13 @@ typedef enum {
void dukky_shuffle_array(duk_context *ctx, duk_uarridx_t idx);
+/* pcall something, and if it errored, also dump the error to the log */
+duk_int_t dukky_pcall(duk_context *ctx, duk_size_t argc, bool reset_timeout);
+
+/* Push a generics function onto the stack */
+void dukky_push_generics(duk_context *ctx, const char *generic);
+
+/* Log the current stack frame if possible */
+void dukky_log_stack_frame(duk_context *ctx, const char * reason);
+
#endif
diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c
index d6a4e31..47621f0 100644
--- a/content/handlers/javascript/duktape/duktape.c
+++ b/content/handlers/javascript/duktape/duktape.c
@@ -1,7 +1,7 @@
/* Omit from static analysis. */
#ifndef __clang_analyzer__
/*
- * Single source autogenerated distributable for Duktape 2.3.0.
+ * Single source autogenerated distributable for Duktape 2.4.0.
*
* Git commit external (external).
* Git branch external.
@@ -18,7 +18,7 @@
*
* (http://opensource.org/licenses/MIT)
*
-* Copyright (c) 2013-2018 by Duktape authors (see AUTHORS.rst)
+* Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -97,6 +97,15 @@
* * Michal Kasperek (https://github.com/michalkas)
* * Andrew Janke (https://github.com/apjanke)
* * Steve Fan (https://github.com/stevefan1999)
+* * Edward Betts (https://github.com/edwardbetts)
+* * Ozhan Duz (https://github.com/webfolderio)
+* * Akos Kiss (https://github.com/akosthekiss)
+* * TheBrokenRail (https://github.com/TheBrokenRail)
+* * Jesse Doyle (https://github.com/jessedoyle)
+* * Gero Kuehn (https://github.com/dc6jgk)
+* * James Swift (https://github.com/phraemer)
+* * Luis de Bethencourt (https://github.com/luisbg)
+* * Ian Whyman (https://github.com/v00d00)
*
* Other contributions
* ===================
@@ -137,6 +146,8 @@
* * Neil Kolban (https://github.com/nkolban)
* * Wilhelm Wanecek (https://github.com/wanecek)
* * Andrew Janke (https://github.com/apjanke)
+* * Unamer (https://github.com/unamer)
+* * Karl Dahlke (eklhad(a)gmail.com)
*
* If you are accidentally missing from this list, send me an e-mail
* (``sami.vaarala(a)iki.fi``) and I'll fix the omission.
@@ -179,13 +190,6 @@
#include "duktape.h"
/*
- * User declarations, e.g. prototypes for user functions used by Duktape
- * macros.
- */
-
-DUK_USE_USER_DECLARE()
-
-/*
* Duktape includes (other than duk_features.h)
*
* The header files expect to be included in an order which satisfies header
@@ -1471,6 +1475,13 @@ DUK_INTERNAL_DECL DUK_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv,
DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x);
#endif
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv);
+#define DUK_TVAL_ASSERT_VALID(tv) do { duk_tval_assert_valid((tv)); } while (0)
+#else
+#define DUK_TVAL_ASSERT_VALID(tv) do {} while (0)
+#endif
+
#endif /* DUK_TVAL_H_INCLUDED */
/* #include duk_builtins.h */
/*
@@ -2016,6 +2027,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx);
@@ -2056,6 +2068,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_hasinstance(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx);
@@ -2111,6 +2124,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_toprimitive(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx);
@@ -2151,6 +2165,9 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *c
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx);
@@ -2177,7 +2194,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_conte
DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[177];
+DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[183];
#endif /* !DUK_SINGLE_FILE */
#define DUK_BIDX_GLOBAL 0
#define DUK_BIDX_GLOBAL_ENV 1
@@ -2232,22 +2249,22 @@ DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[177];
#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 50
#define DUK_NUM_BUILTINS 51
#define DUK_NUM_BIDX_BUILTINS 51
-#define DUK_NUM_ALL_BUILTINS 78
+#define DUK_NUM_ALL_BUILTINS 79
#if defined(DUK_USE_DOUBLE_LE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 4116
+#define DUK_BUILTINS_DATA_LENGTH 4251
#elif defined(DUK_USE_DOUBLE_BE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 4116
+#define DUK_BUILTINS_DATA_LENGTH 4251
#elif defined(DUK_USE_DOUBLE_ME)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 4116
+#define DUK_BUILTINS_DATA_LENGTH 4251
#else
#error invalid endianness defines
#endif
@@ -2416,24 +2433,20 @@ struct duk_bufwriter_ctx {
(const char *) (bw_ctx)->p_base, \
(duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \
} while (0)
+
/* Pointers may be NULL for a while when 'buf' size is zero and before any
* ENSURE calls have been made. Once an ENSURE has been made, the pointers
* are required to be non-NULL so that it's always valid to use memcpy() and
* memmove(), even for zero size.
*/
-#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx) \
- DUK_ASSERT_EXPR((bw_ctx) != NULL && \
- (bw_ctx)->buf != NULL && \
- ((DUK_HBUFFER_DYNAMIC_GET_SIZE((bw_ctx)->buf) == 0) || \
- ((bw_ctx)->p != NULL && \
- (bw_ctx)->p_base != NULL && \
- (bw_ctx)->p_limit != NULL && \
- (bw_ctx)->p_limit >= (bw_ctx)->p_base && \
- (bw_ctx)->p >= (bw_ctx)->p_base && \
- (bw_ctx)->p <= (bw_ctx)->p_limit)))
-#define DUK_BW_ASSERT_VALID(thr,bw_ctx) do { \
- DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);
+#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx) (duk_bw_assert_valid((thr), (bw_ctx)))
+#define DUK_BW_ASSERT_VALID(thr,bw_ctx) do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0)
+#else
+#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx) DUK_ASSERT_EXPR(1)
+#define DUK_BW_ASSERT_VALID(thr,bw_ctx) do {} while (0)
+#endif
/* Working with the pointer and current size. */
@@ -3121,7 +3134,7 @@ DUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);
#define DUK_STR_CALLSTACK_LIMIT "callstack limit"
#define DUK_STR_PROTOTYPE_CHAIN_LIMIT "prototype chain limit"
#define DUK_STR_BOUND_CHAIN_LIMIT "function call bound chain limit"
-#define DUK_STR_C_CALLSTACK_LIMIT "C call stack depth limit"
+#define DUK_STR_NATIVE_STACK_LIMIT "C stack depth limit"
#define DUK_STR_COMPILER_RECURSION_LIMIT "compiler recursion limit"
#define DUK_STR_BYTECODE_LIMIT "bytecode limit"
#define DUK_STR_REG_LIMIT "register limit"
@@ -4654,25 +4667,17 @@ struct duk_heaphdr_string {
/* Check that prev/next links are consistent: if e.g. h->prev is != NULL,
* h->prev->next should point back to h.
*/
-#if defined(DUK_USE_DOUBLE_LINKED_HEAP) && defined(DUK_USE_ASSERTIONS)
-#define DUK_ASSERT_HEAPHDR_LINKS(heap,h) do { \
- if ((h) != NULL) { \
- duk_heaphdr *h__prev, *h__next; \
- h__prev = DUK_HEAPHDR_GET_PREV((heap), (h)); \
- h__next = DUK_HEAPHDR_GET_NEXT((heap), (h)); \
- DUK_ASSERT(h__prev == NULL || (DUK_HEAPHDR_GET_NEXT((heap), h__prev) == (h))); \
- DUK_ASSERT(h__next == NULL || (DUK_HEAPHDR_GET_PREV((heap), h__next) == (h))); \
- } \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h);
+DUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h);
+DUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h);
+#define DUK_HEAPHDR_ASSERT_LINKS(heap,h) do { duk_heaphdr_assert_links((heap), (h)); } while (0)
+#define DUK_HEAPHDR_ASSERT_VALID(h) do { duk_heaphdr_assert_valid((h)); } while (0)
#else
-#define DUK_ASSERT_HEAPHDR_LINKS(heap,h) do {} while (0)
+#define DUK_HEAPHDR_ASSERT_LINKS(heap,h) do {} while (0)
+#define DUK_HEAPHDR_ASSERT_VALID(h) do {} while (0)
#endif
-#define DUK_ASSERT_HEAPHDR_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((h))); \
- } while (0)
-
#endif /* DUK_HEAPHDR_H_INCLUDED */
/* #include duk_refcount.h */
/*
@@ -5409,8 +5414,6 @@ DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h)
#if !defined(DUK_API_INTERNAL_H_INCLUDED)
#define DUK_API_INTERNAL_H_INCLUDED
-#define DUK_INTERNAL_SYMBOL(x) ("\x82" x)
-
/* duk_push_sprintf constants */
#define DUK_PUSH_SPRINTF_INITIAL_SIZE 256L
#define DUK_PUSH_SPRINTF_SANITY_LIMIT (1L * 1024L * 1024L * 1024L)
@@ -5503,6 +5506,8 @@ DUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t
DUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);
+DUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx);
+
DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);
DUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);
DUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);
@@ -5629,6 +5634,14 @@ DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk
duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */
+DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx);
+DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);
+DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \
+ (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \
+ DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \
+ duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
+
DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [val] -> [] */
DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \
@@ -5696,8 +5709,6 @@ DUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t id
DUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);
#endif
-DUK_INTERNAL_DECL void duk_require_constructor_call(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx);
DUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);
DUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);
@@ -5730,6 +5741,8 @@ DUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t n
DUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);
#endif
+DUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx);
+
/* Raw internal valstack access macros: access is unsafe so call site
* must have a guarantee that the index is valid. When that is the case,
* using these macro results in faster and smaller code than duk_get_tval().
@@ -5928,6 +5941,14 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#define DUK_SYMBOL_TYPE_LOCAL 2
#define DUK_SYMBOL_TYPE_WELLKNOWN 3
+/* Assertion for duk_hstring validity. */
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h);
+#define DUK_HSTRING_ASSERT_VALID(h) do { duk_hstring_assert_valid((h)); } while (0)
+#else
+#define DUK_HSTRING_ASSERT_VALID(h) do {} while (0)
+#endif
+
/*
* Misc
*/
@@ -6339,26 +6360,12 @@ DUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);
* Assert for currently guaranteed relations between flags, for instance.
*/
-#define DUK_ASSERT_HOBJECT_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE((h)) || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FUNCTION); \
- DUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ((h)) || \
- (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAYBUFFER || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DATAVIEW || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT8ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT8ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT16ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT16ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT32ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT32ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT32ARRAY || \
- DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT64ARRAY)); \
- /* Object is an Array <=> object has exotic array behavior */ \
- DUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))) || \
- (DUK_HOBJECT_GET_CLASS_NUMBER((h)) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY((h)))); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);
+#define DUK_HOBJECT_ASSERT_VALID(h) do { duk_hobject_assert_valid((h)); } while (0)
+#else
+#define DUK_HOBJECT_ASSERT_VALID(h) do {} while (0)
+#endif
/*
* Macros to access the 'props' allocation.
@@ -6909,18 +6916,13 @@ DUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,
#endif
/* low-level property functions */
-DUK_INTERNAL_DECL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
-DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);
-DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);
-DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);
-/* XXX: when optimizing for guaranteed property slots, use a guaranteed
- * slot for internal value; this call can then access it directly.
- */
-#define duk_hobject_get_internal_value_tval_ptr(heap,obj) \
- duk_hobject_find_existing_entry_tval_ptr((heap), (obj), DUK_HEAP_STRING_INT_VALUE((heap)))
-
/* core property functions */
DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);
@@ -6964,8 +6966,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthr
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);
/* internal properties */
-DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobject *obj, duk_tval *tv);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj);
DUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);
+DUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj);
+DUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj);
/* hobject management functions */
DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);
@@ -7136,9 +7140,12 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);
* Validity assert
*/
-#define DUK_ASSERT_HCOMPFUNC_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h);
+#define DUK_HCOMPFUNC_ASSERT_VALID(h) do { duk_hcompfunc_assert_valid((h)); } while (0)
+#else
+#define DUK_HCOMPFUNC_ASSERT_VALID(h) do {} while (0)
+#endif
/*
* Main struct
@@ -7281,6 +7288,13 @@ struct duk_hcompfunc {
#if !defined(DUK_HNATFUNC_H_INCLUDED)
#define DUK_HNATFUNC_H_INCLUDED
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h);
+#define DUK_HNATFUNC_ASSERT_VALID(h) do { duk_hnatfunc_assert_valid((h)); } while (0)
+#else
+#define DUK_HNATFUNC_ASSERT_VALID(h) do {} while (0)
+#endif
+
#define DUK_HNATFUNC_NARGS_VARARGS ((duk_int16_t) -1)
#define DUK_HNATFUNC_NARGS_MAX ((duk_int16_t) 0x7fff)
@@ -7319,15 +7333,12 @@ struct duk_hnatfunc {
*/
#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL
-#define DUK_ASSERT_HBOUNDFUNC_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) (h))); \
- DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&(h)->target) || \
- (DUK_TVAL_IS_OBJECT(&(h)->target) && \
- DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&(h)->target)))); \
- DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&(h)->this_binding)); \
- DUK_ASSERT((h)->nargs == 0 || (h)->args != NULL); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h);
+#define DUK_HBOUNDFUNC_ASSERT_VALID(h) do { duk_hboundfunc_assert_valid((h)); } while (0)
+#else
+#define DUK_HBOUNDFUNC_ASSERT_VALID(h) do {} while (0)
+#endif
struct duk_hboundfunc {
/* Shared object part. */
@@ -7369,32 +7380,12 @@ struct duk_hboundfunc {
#define DUK_HBUFOBJ_ELEM_FLOAT64 8
#define DUK_HBUFOBJ_ELEM_MAX 8
-#define DUK_ASSERT_HBUFOBJ_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT((h)->shift <= 3); \
- DUK_ASSERT((h)->elem_type <= DUK_HBUFOBJ_ELEM_MAX); \
- DUK_ASSERT(((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT8) || \
- ((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) || \
- ((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT8) || \
- ((h)->shift == 1 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT16) || \
- ((h)->shift == 1 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT16) || \
- ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT32) || \
- ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT32) || \
- ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) || \
- ((h)->shift == 3 && (h)->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64)); \
- DUK_ASSERT((h)->is_typedarray == 0 || (h)->is_typedarray == 1); \
- DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) (h))); \
- if ((h)->buf == NULL) { \
- DUK_ASSERT((h)->offset == 0); \
- DUK_ASSERT((h)->length == 0); \
- } else { \
- /* No assertions for offset or length; in particular, \
- * it's OK for length to be longer than underlying \
- * buffer. Just ensure they don't wrap when added. \
- */ \
- DUK_ASSERT((h)->offset + (h)->length >= (h)->offset); \
- } \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h);
+#define DUK_HBUFOBJ_ASSERT_VALID(h) do { duk_hbufobj_assert_valid((h)); } while (0)
+#else
+#define DUK_HBUFOBJ_ASSERT_VALID(h) do {} while (0)
+#endif
/* Get the current data pointer (caller must ensure buf != NULL) as a
* duk_uint8_t ptr. Note that the result may be NULL if the underlying
@@ -7489,6 +7480,10 @@ DUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbu
DUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+
+/* nothing */
+
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#endif /* DUK_HBUFOBJ_H_INCLUDED */
/* #include duk_hthread.h */
@@ -7638,37 +7633,24 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx
* diagnose behavior so it's worth checking even when the check is not 100%.
*/
+#if defined(DUK_USE_ASSERTIONS)
/* Assertions for internals. */
-#define DUK_ASSERT_HTHREAD_VALID(thr) do { \
- DUK_ASSERT((thr) != NULL); \
- DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) (thr)) == DUK_HTYPE_OBJECT); \
- DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) (thr))); \
- DUK_ASSERT((thr)->unused1 == 0); \
- DUK_ASSERT((thr)->unused2 == 0); \
- } while (0)
+DUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr);
+#define DUK_HTHREAD_ASSERT_VALID(thr) do { duk_hthread_assert_valid((thr)); } while (0)
/* Assertions for public API calls; a bit stronger. */
-#define DUK_ASSERT_CTX_VALID(thr) do { \
- DUK_ASSERT((thr) != NULL); \
- DUK_ASSERT_HTHREAD_VALID((thr)); \
- DUK_ASSERT((thr)->valstack != NULL); \
- DUK_ASSERT((thr)->valstack_bottom != NULL); \
- DUK_ASSERT((thr)->valstack_top != NULL); \
- DUK_ASSERT((thr)->valstack_end != NULL); \
- DUK_ASSERT((thr)->valstack_alloc_end != NULL); \
- DUK_ASSERT((thr)->valstack_alloc_end >= (thr)->valstack); \
- DUK_ASSERT((thr)->valstack_end >= (thr)->valstack); \
- DUK_ASSERT((thr)->valstack_top >= (thr)->valstack); \
- DUK_ASSERT((thr)->valstack_top >= (thr)->valstack_bottom); \
- DUK_ASSERT((thr)->valstack_end >= (thr)->valstack_top); \
- DUK_ASSERT((thr)->valstack_alloc_end >= (thr)->valstack_end); \
- } while (0)
+DUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr);
+#define DUK_CTX_ASSERT_VALID(thr) do { duk_ctx_assert_valid((thr)); } while (0)
+#else
+#define DUK_HTHREAD_ASSERT_VALID(thr) do {} while (0)
+#define DUK_CTX_ASSERT_VALID(thr) do {} while (0)
+#endif
/* Assertions for API call entry specifically. Checks 'ctx' but also may
* check internal state (e.g. not in a debugger transport callback).
*/
#define DUK_ASSERT_API_ENTRY(thr) do { \
- DUK_ASSERT_CTX_VALID((thr)); \
+ DUK_CTX_ASSERT_VALID((thr)); \
DUK_ASSERT((thr)->heap != NULL); \
DUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \
} while (0)
@@ -7925,11 +7907,12 @@ DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);
#if !defined(DUK_HARRAY_H_INCLUDED)
#define DUK_HARRAY_H_INCLUDED
-#define DUK_ASSERT_HARRAY_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) (h))); \
- DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) (h))); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h);
+#define DUK_HARRAY_ASSERT_VALID(h) do { duk_harray_assert_valid((h)); } while (0)
+#else
+#define DUK_HARRAY_ASSERT_VALID(h) do {} while (0)
+#endif
#define DUK_HARRAY_LENGTH_WRITABLE(h) (!(h)->length_nonwritable)
#define DUK_HARRAY_LENGTH_NONWRITABLE(h) ((h)->length_nonwritable)
@@ -7969,18 +7952,15 @@ struct duk_harray {
#if !defined(DUK_HENV_H_INCLUDED)
#define DUK_HENV_H_INCLUDED
-#define DUK_ASSERT_HDECENV_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) (h))); \
- DUK_ASSERT((h)->thread == NULL || (h)->varmap != NULL); \
- } while (0)
-
-#define DUK_ASSERT_HOBJENV_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) (h))); \
- DUK_ASSERT((h)->target != NULL); \
- DUK_ASSERT((h)->has_this == 0 || (h)->has_this == 1); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h);
+DUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h);
+#define DUK_HDECENV_ASSERT_VALID(h) do { duk_hdecenv_assert_valid((h)); } while (0)
+#define DUK_HOBJENV_ASSERT_VALID(h) do { duk_hobjenv_assert_valid((h)); } while (0)
+#else
+#define DUK_HDECENV_ASSERT_VALID(h) do {} while (0)
+#define DUK_HOBJENV_ASSERT_VALID(h) do {} while (0)
+#endif
struct duk_hdecenv {
/* Shared object part. */
@@ -8175,6 +8155,14 @@ struct duk_hobjenv {
)
#endif
+/* Validity assert. */
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h);
+#define DUK_HBUFFER_ASSERT_VALID(h) do { duk_hbuffer_assert_valid((h)); } while (0)
+#else
+#define DUK_HBUFFER_ASSERT_VALID(h) do {} while (0)
+#endif
+
/*
* Structs
*/
@@ -8347,12 +8335,12 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *
#if !defined(DUK_HPROXY_H_INCLUDED)
#define DUK_HPROXY_H_INCLUDED
-#define DUK_ASSERT_HPROXY_VALID(h) do { \
- DUK_ASSERT((h) != NULL); \
- DUK_ASSERT((h)->target != NULL); \
- DUK_ASSERT((h)->handler != NULL); \
- DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) (h))); \
- } while (0)
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h);
+#define DUK_HPROXY_ASSERT_VALID(h) do { duk_hproxy_assert_valid((h)); } while (0)
+#else
+#define DUK_HPROXY_ASSERT_VALID(h) do {} while (0)
+#endif
struct duk_hproxy {
/* Shared object part. */
@@ -8707,6 +8695,13 @@ struct duk_litcache_entry {
* Main heap structure
*/
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap);
+#define DUK_HEAP_ASSERT_VALID(heap) do { duk_heap_assert_valid((heap)); } while (0)
+#else
+#define DUK_HEAP_ASSERT_VALID(heap) do {} while (0)
+#endif
+
struct duk_heap {
duk_small_uint_t flags;
@@ -8778,6 +8773,11 @@ struct duk_heap {
/* Mark-and-sweep running flag. Prevents re-entry, and also causes
* refzero events to be ignored (= objects won't be queued to refzero_list).
+ *
+ * 0: mark-and-sweep not running
+ * 1: mark-and-sweep is running
+ * 2: heap destruction active or debugger active, prevent mark-and-sweep
+ * and refzero processing (but mark-and-sweep not itself running)
*/
duk_uint_t ms_running;
@@ -8996,6 +8996,11 @@ struct duk_heap {
duk_int_t stats_putprop_proxy;
duk_int_t stats_getvar_all;
duk_int_t stats_putvar_all;
+ duk_int_t stats_envrec_delayedcreate;
+ duk_int_t stats_envrec_create;
+ duk_int_t stats_envrec_newenv;
+ duk_int_t stats_envrec_oldenv;
+ duk_int_t stats_envrec_pushclosure;
#endif
};
@@ -9597,6 +9602,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_UNSUPPORTED(thr) do { \
DUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \
} while (0)
+#define DUK_DCERROR_UNSUPPORTED(thr) do { \
+ DUK_ERROR_UNSUPPORTED((thr)); \
+ return 0; \
+ } while (0)
#define DUK_ERROR_ERROR(thr,msg) do { \
duk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \
} while (0)
@@ -9685,6 +9694,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_UNSUPPORTED(thr) do { \
duk_err_error((thr)); \
} while (0)
+#define DUK_DCERROR_UNSUPPORTED(thr) do { \
+ DUK_UNREF((thr)); \
+ return DUK_RET_ERROR; \
+ } while (0)
#define DUK_ERROR_ERROR(thr,msg) do { \
duk_err_error((thr)); \
} while (0)
@@ -10117,13 +10130,13 @@ DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, d
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_ids_noa[1063];
+extern const duk_uint8_t duk_unicode_ids_noa[1116];
#else
/*
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_ids_noabmp[626];
+extern const duk_uint8_t duk_unicode_ids_noabmp[625];
#endif
#if defined(DUK_USE_SOURCE_NONBMP)
@@ -10145,7 +10158,7 @@ extern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24];
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_idp_m_ids_noa[549];
+extern const duk_uint8_t duk_unicode_idp_m_ids_noa[576];
#else
/*
* Automatically generated by extract_chars.py, do not edit!
@@ -10158,8 +10171,8 @@ extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358];
* Automatically generated by extract_caseconv.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_caseconv_uc[1386];
-extern const duk_uint8_t duk_unicode_caseconv_lc[680];
+extern const duk_uint8_t duk_unicode_caseconv_uc[1411];
+extern const duk_uint8_t duk_unicode_caseconv_lc[706];
#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)
/*
@@ -10392,12 +10405,13 @@ DUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,
duk_bool_t add_auto_proto);
/* call handling */
+DUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr);
DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);
DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);
DUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);
DUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);
#if defined(DUK_USE_VERBOSE_ERRORS)
-DUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_targ, duk_tval *tv_base, duk_tval *tv_key);
+DUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key);
#endif
/* bytecode execution */
@@ -10842,8 +10856,8 @@ DUK_INTERNAL const duk_uint8_t duk_strings_data[967] = {
#if defined(DUK_USE_ROM_OBJECTS)
#error ROM support not enabled, rerun configure.py with --rom-support
#else /* DUK_USE_ROM_OBJECTS */
-/* native functions: 177 */
-DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
+/* native functions: 183 */
+DUK_INTERNAL const duk_c_function duk_bi_native_functions[183] = {
NULL,
duk_bi_array_constructor,
duk_bi_array_constructor_is_array,
@@ -10879,6 +10893,7 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
duk_bi_date_prototype_set_shared,
duk_bi_date_prototype_set_time,
duk_bi_date_prototype_to_json,
+ duk_bi_date_prototype_toprimitive,
duk_bi_date_prototype_tostring_shared,
duk_bi_date_prototype_value_of,
duk_bi_duktape_object_act,
@@ -10901,6 +10916,7 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
duk_bi_function_prototype_apply,
duk_bi_function_prototype_bind,
duk_bi_function_prototype_call,
+ duk_bi_function_prototype_hasinstance,
duk_bi_function_prototype_to_string,
duk_bi_global_object_decode_uri,
duk_bi_global_object_decode_uri_component,
@@ -11003,6 +11019,10 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
duk_bi_string_prototype_substring,
duk_bi_string_prototype_to_string,
duk_bi_string_prototype_trim,
+ duk_bi_symbol_constructor_shared,
+ duk_bi_symbol_key_for,
+ duk_bi_symbol_toprimitive,
+ duk_bi_symbol_tostring_shared,
duk_bi_textdecoder_constructor,
duk_bi_textdecoder_prototype_decode,
duk_bi_textdecoder_prototype_shared_getter,
@@ -11023,275 +11043,283 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
duk_bi_uint8array_plainof,
};
#if defined(DUK_USE_DOUBLE_LE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
-144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
-124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
-167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
-64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
-142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
-242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
-174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
-248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
-128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
-154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
-249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
-136,67,134,19,49,0,0,0,0,0,0,3,225,255,51,0,0,0,0,0,0,3,193,255,47,18,1,
-172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
-149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
-141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
-132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
-96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
-243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
-79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
-147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
-121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
-151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
-180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
-78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
-146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
-70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
-55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
-96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
-103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
-1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
-46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
-217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
-241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
-96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
-46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
-194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
-109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
-240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
-174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
-104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
-194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
-16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
-129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
-224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
-248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
-124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
-131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
-192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
-255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
-245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
-163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
-5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
-34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
-211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
-22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
-197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
-127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
-132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
-190,120,35,11,60,4,25,68,81,61,96,47,181,80,46,132,129,255,255,255,255,255,
-255,222,254,39,172,67,118,170,5,208,144,0,64,0,0,0,0,0,0,51,16,0,0,0,0,0,0,
-62,31,200,245,238,146,38,138,147,105,13,42,26,137,226,0,0,0,0,0,0,7,131,
-249,30,180,134,4,209,82,109,33,165,67,81,60,64,0,0,0,0,0,0,240,255,15,210,
-62,72,91,155,0,0,0,0,0,0,2,192,240,135,88,11,237,72,5,38,210,27,50,24,145,
-129,255,255,255,255,255,254,126,134,67,172,67,118,164,2,147,105,13,153,12,
-72,192,255,255,255,255,255,255,63,195,16,240,70,68,226,27,51,199,138,120,
-35,34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,
-144,196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,
-142,224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,
-224,3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,
-92,221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,
-210,98,177,252,3,107,173,88,3,146,211,141,32,0,0,0,0,0,3,225,255,19,175,
-188,0,100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,
-161,166,188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,
-18,155,184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,
-8,77,133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,
-32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,
-57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
-153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
-144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,
-22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,
-166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,
-39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,
-32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,
-68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,
-16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,
-11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,
-36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,
-191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,
-43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,
-201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
-123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
-215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
-131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
-176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
-127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
-57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
-191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
-80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
-220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
-27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
-186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
-28,24,61,73,25,33,205,128,0,0,0,0,1,167,166,129,108,242,151,15,39,8,34,26,
-87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
-130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
-80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
-139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
-0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
-0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
-130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
-62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
-159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
-133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
-62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
-217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
-244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
-158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
-196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,168,71,
-161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,200,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,
-232,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,155,52,
-8,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,155,52,40,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,52,72,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,52,
-104,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,
-52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,1,2,1,135,
-52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
-50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
-214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
-136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
-161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
-171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
-4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
-89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
-29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
-207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
-235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
-108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
-155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
-122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
-218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
-75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
-137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
-131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
-73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
-117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
-226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
-114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
-162,137,147,111,2,8,4,16,7,8,96,120,72,13,42,226,145,97,87,224,168,1,58,
-182,232,232,64,22,85,181,187,177,107,2,64,7,213,183,74,7,121,207,215,242,
-17,119,49,248,94,173,198,210,36,15,232,34,182,84,113,95,115,240,221,91,141,
-163,160,72,1,220,164,194,175,121,123,103,224,186,244,64,24,45,68,84,251,33,
-9,64,15,217,66,51,209,218,210,129,154,118,254,205,61,65,204,126,23,178,132,
-103,165,3,52,237,253,154,122,131,216,254,168,48,6,90,130,1,0,39,75,80,72,8,
-9,33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,128,
-65,17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,234,10,
-8,41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,141,
-168,40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,47,0,
-216,134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,209,
-234,10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,192,
-115,3,117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,113,67,
-76,130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,1,78,
-192,56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,147,
-182,140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,188,24,
-49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,14,49,
-39,199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,35,
-100,128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,28,
-217,114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,32,
-225,64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,76,
-156,113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,
-114,1,18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,0,0,0,0,0,0,120,31,153,172,56,132,122,28,76,146,218,121,
-35,180,69,145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,
-184,0,0,175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,180,
-242,71,104,139,35,8,217,192,0,0,0,0,0,0,240,63,51,88,145,8,244,56,153,37,
-180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,88,161,8,244,56,153,37,
-180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,88,177,8,244,56,153,37,
-180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,193,8,244,56,153,
-37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,209,8,244,56,
-153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,225,8,244,
-56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,
-97,57,162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,
-29,153,1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,
-112,28,211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,
-240,117,32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,
-148,25,174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,
-214,3,192,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {
+144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,
+124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,
+167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,
+64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,
+242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,
+1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,
+174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,
+228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,
+224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,
+245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,
+108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,
+124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,0,0,0,0,62,31,243,48,
+0,0,0,0,0,0,60,31,242,241,32,26,193,55,132,112,161,156,72,135,26,41,200,
+140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,
+116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,
+145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,
+181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,
+249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,
+121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,
+240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,
+17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,
+186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,
+53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,
+185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,
+218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,
+128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,
+53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,
+186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,
+82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,
+152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,
+144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,
+114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,
+57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,
+11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,
+194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,
+116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,
+201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,
+100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,
+230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,
+137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,
+135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,
+7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,
+250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,
+160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,
+163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,
+146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,
+52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,
+40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,
+124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,
+246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,
+201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,
+192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,
+224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,
+72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,
+185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,
+193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,
+147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,
+42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,
+186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,
+130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,255,255,255,255,
+253,239,226,122,196,55,106,160,93,9,0,4,0,0,0,0,0,0,3,49,0,0,0,0,0,0,3,225,
+252,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,63,145,
+235,72,96,77,21,38,210,26,84,53,19,196,0,0,0,0,0,0,15,15,240,253,35,228,
+133,185,176,0,0,0,0,0,0,44,15,8,117,128,190,212,128,82,109,33,179,33,137,
+24,31,255,255,255,255,255,231,232,100,58,196,55,106,64,41,54,144,217,144,
+196,140,15,255,255,255,255,255,243,252,49,15,4,100,78,33,179,60,120,167,
+130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,
+153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,
+72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,
+60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,
+205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,
+43,31,192,54,186,213,128,57,45,56,210,0,0,0,0,0,0,62,31,241,90,251,224,6,
+77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,
+224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,
+113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,
+61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,
+175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,
+39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,
+240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,
+197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,
+150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,
+161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,
+100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,
+18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,
+72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,
+46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,
+117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,
+178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,
+173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,
+117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,
+131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,
+102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,
+162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,
+192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,
+200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,
+117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,
+95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,
+89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,
+98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,
+165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,
+19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,
+160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,
+71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,0,118,
+105,160,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,
+228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,
+131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,
+89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,
+208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,
+202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,
+152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,
+227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,
+192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,
+137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,
+159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,
+79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,
+13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,
+71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,
+77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,
+165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,
+0,0,0,0,3,192,252,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,
+103,0,0,0,0,0,0,3,192,252,206,25,244,35,208,226,100,150,211,201,29,162,44,
+140,35,103,0,0,0,0,0,0,3,192,252,206,26,4,35,208,226,100,150,211,201,29,
+162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,20,35,208,226,100,150,211,201,
+29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,36,35,208,226,100,150,211,
+201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,52,35,208,226,100,150,
+211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,68,35,208,226,100,
+150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,84,35,208,226,
+100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,129,0,195,154,99,16,38,
+36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,
+162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,
+162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,
+58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,
+237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,
+77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,
+40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,
+89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,
+125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,
+213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,
+216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,
+122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,
+40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,
+148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,
+157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,
+146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,
+173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,
+38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,
+166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,
+217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,
+13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,
+80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,
+201,185,129,4,2,8,3,132,64,60,36,6,149,113,72,176,171,240,84,0,157,91,116,
+116,32,11,42,218,221,216,181,129,32,3,234,219,165,3,188,231,235,249,8,187,
+152,252,47,86,227,105,18,7,244,17,91,42,56,175,185,248,110,173,198,209,208,
+36,0,238,82,97,87,188,189,179,240,93,122,32,12,22,162,42,125,144,132,160,7,
+236,161,25,232,237,105,64,205,59,127,102,158,160,230,63,11,217,66,51,210,
+129,154,118,254,205,61,65,236,127,171,197,34,168,48,6,90,162,1,0,39,75,84,
+72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,
+128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,
+234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,
+91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,
+212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,
+168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,
+192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,
+113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,
+1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,
+147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,
+188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,
+14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,
+35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,
+28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,
+209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,
+201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,
+221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,
+250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,
+131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,
+75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,
+160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,
+108,224,0,0,0,0,0,0,120,31,153,188,56,132,122,28,76,146,218,121,35,180,69,
+145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,184,0,0,181,
+32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,
+139,35,8,217,192,0,0,0,0,0,0,240,63,51,120,145,8,244,56,153,37,180,242,71,
+104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,161,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,177,8,244,56,153,37,180,
+242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,193,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,209,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,225,8,244,56,
+153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,97,
+57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,
+169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,
+211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,
+84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,
+226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,
+30,224,32,54,186,221,128,60,
};
#elif defined(DUK_USE_DOUBLE_BE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
-144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
-124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
-167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
-64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
-142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
-242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
-174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
-248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
-128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
-154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
-249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
-136,67,134,19,49,1,255,224,0,0,0,0,0,3,51,1,255,192,0,0,0,0,0,3,47,18,1,
-172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
-149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
-141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
-132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
-96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
-243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
-79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
-147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
-121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
-151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
-180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
-78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
-146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
-70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
-55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
-96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
-103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
-1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
-46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
-217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
-241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
-96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
-46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
-194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
-109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
-240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
-174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
-104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
-194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
-16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
-129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
-224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
-248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
-124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
-131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
-192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
-255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
-245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
-163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
-5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
-34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
-211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
-22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
-197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
-127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
-132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
-190,120,35,11,60,4,25,68,81,61,96,47,181,80,46,132,128,255,223,255,255,255,
-255,255,254,39,172,67,118,170,5,208,144,0,0,0,0,0,0,0,0,115,16,31,254,0,0,
-0,0,0,0,8,245,238,146,38,138,147,105,13,42,26,137,226,3,255,128,0,0,0,0,0,
-1,30,180,134,4,209,82,109,33,165,67,81,60,64,255,240,0,0,0,0,0,0,15,210,62,
-72,91,155,0,242,192,0,0,0,0,0,0,135,88,11,237,72,5,38,210,27,50,24,145,128,
-134,127,255,255,255,255,255,254,67,172,67,118,164,2,147,105,13,153,12,72,
-192,195,63,255,255,255,255,255,255,16,240,70,68,226,27,51,199,138,120,35,
-34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,144,
-196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,142,
-224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,224,
-3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,92,
-221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,210,
-98,177,252,3,107,173,88,3,146,211,141,33,255,224,0,0,0,0,0,3,19,175,188,0,
-100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,161,166,
-188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,18,155,
-184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,8,77,
-133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,32,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {
+144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,
+124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,
+167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,
+64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,
+242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,
+1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,
+174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,
+228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,
+224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,
+245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,
+108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,
+124,153,47,62,12,130,112,201,24,132,56,97,115,16,31,254,0,0,0,0,0,0,51,48,
+31,252,0,0,0,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,
+140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,
+116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,
+145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,
+181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,
+249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,
+121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,
+240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,
+17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,
+186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,
+53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,
+185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,
+218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,
+128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,
+53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,
+186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,
+82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,
+152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,
+144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,
+114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,
+57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,
+11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,
+194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,
+116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,
+201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,
+100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,
+230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,
+137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,
+135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,
+7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,
+250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,
+160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,
+163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,
+146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,
+52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,
+40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,
+124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,
+246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,
+201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,
+192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,
+224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,
+72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,
+185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,
+193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,
+147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,
+42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,
+186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,
+130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,15,253,255,255,255,255,
+255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,0,0,0,7,49,1,255,224,0,0,0,0,
+0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,63,248,0,0,0,0,0,0,17,
+235,72,96,77,21,38,210,26,84,53,19,196,15,255,0,0,0,0,0,0,0,253,35,228,133,
+185,176,15,44,0,0,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,24,8,
+103,255,255,255,255,255,255,228,58,196,55,106,64,41,54,144,217,144,196,140,
+12,51,255,255,255,255,255,255,241,15,4,100,78,33,179,60,120,167,130,50,39,
+10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,153,12,72,
+238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,72,238,
+137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,60,221,
+194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,205,220,
+124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,43,31,192,
+54,186,213,128,57,45,56,210,31,254,0,0,0,0,0,0,49,90,251,224,6,77,220,24,
+38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,224,172,37,
+240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,113,41,187,
+139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,61,240,132,
+216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,175,152,32,
35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,57,
179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
@@ -11309,291 +11337,304 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
-131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
-176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
-127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
-57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
-191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
-80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
-220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
-27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
-186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
-28,24,61,73,25,33,205,128,129,167,166,0,0,0,0,1,108,242,151,15,39,8,34,26,
-87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
-130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
-80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
-139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
-0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
-0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
-130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
-62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
-159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
-133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
-62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
-217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
-244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
-158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
-196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,168,71,
-161,196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,200,
-71,161,196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,
-232,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,155,52,
-8,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,155,52,40,
-71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,52,72,
-71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,52,
-104,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,
-52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,2,1,0,0,0,0,0,0,1,135,
-52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
-50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
-214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
-136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
-161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
-171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
-4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
-89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
-29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
-207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
-235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
-108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
-155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
-122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
-218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
-75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
-137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
-131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
-73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
-117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
-226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
-114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
-162,137,147,111,2,8,4,16,7,8,96,120,72,8,0,183,225,81,98,138,237,33,58,182,
-232,232,64,64,2,107,177,187,181,85,22,7,213,183,74,1,255,49,114,23,247,209,
-207,120,94,173,198,210,36,3,255,113,84,118,82,184,47,224,221,91,141,163,
-160,72,7,251,121,111,98,164,220,161,192,186,244,64,64,9,33,251,84,68,45,24,
-15,217,66,51,209,218,210,128,127,205,65,60,204,254,119,154,23,178,132,103,
-165,0,255,218,130,121,153,252,239,54,168,48,6,90,130,1,0,39,75,80,72,8,9,
-33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,128,65,
-17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,234,10,8,
-41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,141,168,
-40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,47,0,216,
-134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,209,234,
-10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,192,115,3,
-117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,113,67,76,
-130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,1,78,192,
-56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,147,182,
-140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,188,24,49,
-39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,14,49,39,
-199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,35,100,
-128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,28,217,
-114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,32,225,
-64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,76,156,
-113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,114,1,
-18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,69,145,
-132,108,224,31,248,0,0,0,0,0,0,25,172,56,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,
-175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,180,242,71,
-104,139,35,8,217,192,63,240,0,0,0,0,0,0,51,88,145,8,244,56,153,37,180,242,
-71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,88,161,8,244,56,153,37,180,242,
-71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,88,177,8,244,56,153,37,180,242,
-71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,193,8,244,56,153,37,180,
-242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,209,8,244,56,153,37,
-180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,225,8,244,56,153,
-37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,57,
-162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,29,153,
-1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,112,28,
-211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,240,117,
-32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,148,25,
-174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,214,3,
-192,
+131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,200,
+51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,117,
+243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,95,
+231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,89,
+183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,98,
+232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,165,
+19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,19,
+236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,
+89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,71,
+105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,246,0,0,0,
+0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,228,
+1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,131,
+32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,89,56,
+72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,208,211,
+14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,202,10,
+14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,152,80,
+113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,227,224,
+0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,192,131,
+18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,137,62,
+81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,159,40,
+134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,79,133,
+91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,13,158,
+197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,71,90,
+155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,77,
+174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,
+165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,
+255,192,0,0,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,
+103,0,255,192,0,0,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,
+140,35,103,0,255,192,0,0,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,
+162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,
+29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,36,35,208,226,100,150,211,
+201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,52,35,208,226,100,150,
+211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,68,35,208,226,100,
+150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,84,35,208,226,
+100,150,211,201,29,162,44,140,35,103,1,0,128,0,0,0,0,0,0,195,154,99,16,38,
+36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,
+162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,
+162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,
+58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,
+237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,
+77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,
+40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,
+89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,
+125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,
+213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,
+216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,
+122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,
+40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,
+148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,
+157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,
+146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,
+173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,
+38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,
+166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,
+217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,
+13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,
+80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,
+201,185,129,4,2,8,3,132,64,60,36,4,0,91,240,168,177,69,118,144,157,91,116,
+116,32,32,1,53,216,221,218,170,139,3,234,219,165,0,255,152,185,11,251,232,
+231,188,47,86,227,105,18,1,255,184,170,59,41,92,23,240,110,173,198,209,208,
+36,3,253,188,183,177,82,110,80,224,93,122,32,32,4,144,253,170,34,22,140,7,
+236,161,25,232,237,105,64,63,230,160,158,102,127,59,205,11,217,66,51,210,
+128,127,237,65,60,204,254,119,155,171,197,34,168,48,6,90,162,1,0,39,75,84,
+72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,
+128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,
+234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,
+91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,
+212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,
+168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,
+192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,
+113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,
+1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,
+147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,
+188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,
+14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,
+35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,
+28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,
+209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,
+201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,
+221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,
+250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,
+131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,
+75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,
+160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,
+108,224,31,248,0,0,0,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,
+145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,181,
+32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,
+139,35,8,217,192,63,240,0,0,0,0,0,0,51,120,145,8,244,56,153,37,180,242,71,
+104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,161,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,177,8,244,56,153,37,180,
+242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,193,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,209,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,225,8,244,56,
+153,37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,
+57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,
+169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,
+211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,
+84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,
+226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,
+30,224,32,54,186,221,128,60,
};
#elif defined(DUK_USE_DOUBLE_ME)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
-144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
-124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
-167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
-64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
-142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
-242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
-174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
-248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
-128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
-154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
-249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
-136,67,134,19,49,0,0,3,225,252,0,0,0,3,51,0,0,3,193,252,0,0,0,3,47,18,1,
-172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
-149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
-141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
-132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
-96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
-243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
-79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
-147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
-121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
-151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
-180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
-78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
-146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
-70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
-55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
-96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
-103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
-1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
-46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
-217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
-241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
-96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
-46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
-194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
-109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
-240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
-174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
-104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
-194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
-16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
-129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
-224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
-248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
-124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
-131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
-192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
-255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
-245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
-163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
-5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
-34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
-211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
-22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
-197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
-127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
-132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
-190,120,35,11,60,4,25,68,81,61,96,47,181,80,46,132,129,255,255,222,255,255,
-255,255,254,39,172,67,118,170,5,208,144,0,0,0,0,0,64,0,0,51,16,0,0,62,31,
-192,0,0,0,8,245,238,146,38,138,147,105,13,42,26,137,226,0,0,7,131,248,0,0,
-0,1,30,180,134,4,209,82,109,33,165,67,81,60,64,0,0,240,255,0,0,0,0,15,210,
-62,72,91,155,0,0,2,192,240,0,0,0,0,135,88,11,237,72,5,38,210,27,50,24,145,
-129,255,254,126,135,255,255,255,254,67,172,67,118,164,2,147,105,13,153,12,
-72,192,255,255,63,195,255,255,255,255,16,240,70,68,226,27,51,199,138,120,
-35,34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,
-144,196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,
-142,224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,
-224,3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,
-92,221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,
-210,98,177,252,3,107,173,88,3,146,211,141,32,0,3,225,252,0,0,0,3,19,175,
-188,0,100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,
-161,166,188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,
-18,155,184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,
-8,77,133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,
-32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,
-57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
-153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
-144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,
-22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,
-166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,
-39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,
-32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,
-68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,
-16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,
-11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,
-36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,
-191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,
-43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,
-201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
-123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
-215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
-131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
-176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
-127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
-57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
-191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
-80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
-220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
-27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
-186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
-28,24,61,73,25,33,205,128,1,167,166,128,0,0,0,1,108,242,151,15,39,8,34,26,
-87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
-130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
-80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
-139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
-0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
-0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
-130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
-62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
-159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
-133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
-62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
-217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
-244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
-158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
-196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,168,71,
-161,196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,200,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,
-232,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,155,52,
-8,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,155,52,40,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,52,72,
-71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,52,
-104,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,
-52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,1,2,0,0,0,0,1,135,
-52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
-50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
-214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
-136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
-161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
-171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
-4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
-89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
-29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
-207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
-235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
-108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
-155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
-122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
-218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
-75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
-137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
-131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
-73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
-117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
-226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
-114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
-162,137,147,111,2,8,4,16,7,8,96,120,72,1,87,224,168,13,42,226,145,97,58,
-182,232,232,64,177,107,2,64,22,85,181,187,7,213,183,74,2,17,119,49,255,121,
-207,215,240,94,173,198,210,36,4,113,95,115,255,232,34,182,80,221,91,141,
-163,160,72,15,121,123,103,225,220,164,194,160,186,244,64,251,33,9,64,24,45,
-68,84,15,217,66,51,209,218,210,129,61,65,204,127,154,118,254,204,23,178,
-132,103,165,2,122,131,216,255,52,237,253,154,168,48,6,90,130,1,0,39,75,80,
-72,8,9,33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,
-128,65,17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,
-234,10,8,41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,
-141,168,40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,
-47,0,216,134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,
-209,234,10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,
-192,115,3,117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,
-113,67,76,130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,
-1,78,192,56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,
-147,182,140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,
-188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,
-14,49,39,199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,
-35,100,128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,
-28,217,114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,
-32,225,64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,
-76,156,113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,
-114,1,18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,0,0,120,31,128,0,0,0,25,172,56,132,122,28,76,146,218,
-121,35,180,69,145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,
-33,184,0,0,175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,
-180,242,71,104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,88,145,8,244,56,153,
-37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,88,161,8,244,56,153,
-37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,88,177,8,244,56,153,
-37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,193,8,244,56,
-153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,209,8,244,
-56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,225,8,
-244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,
-0,97,57,162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,
-29,153,1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,
-112,28,211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,
-240,117,32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,
-148,25,174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,
-214,3,192,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {
+144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,
+124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,
+167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,
+64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,
+242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,
+1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,
+174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,
+228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,
+224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,
+245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,
+108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,
+124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,62,31,192,0,0,0,51,48,
+0,0,60,31,192,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,
+140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,
+116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,
+145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,
+181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,
+249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,
+121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,
+240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,
+17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,
+186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,
+53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,
+185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,
+218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,
+128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,
+53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,
+186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,
+82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,
+152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,
+144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,
+114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,
+57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,
+11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,
+194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,
+116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,
+201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,
+100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,
+230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,
+137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,
+135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,
+7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,
+250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,
+160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,
+163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,
+146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,
+52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,
+40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,
+124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,
+246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,
+201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,
+192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,
+224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,
+72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,
+185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,
+193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,
+147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,
+42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,
+186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,
+130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,253,239,255,255,
+255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,4,0,0,3,49,0,0,3,225,252,0,0,
+0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,120,63,128,0,0,0,
+17,235,72,96,77,21,38,210,26,84,53,19,196,0,0,15,15,240,0,0,0,0,253,35,228,
+133,185,176,0,0,44,15,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,
+24,31,255,231,232,127,255,255,255,228,58,196,55,106,64,41,54,144,217,144,
+196,140,15,255,243,252,63,255,255,255,241,15,4,100,78,33,179,60,120,167,
+130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,
+153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,
+72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,
+60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,
+205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,
+43,31,192,54,186,213,128,57,45,56,210,0,0,62,31,192,0,0,0,49,90,251,224,6,
+77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,
+224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,
+113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,
+61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,
+175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,
+39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,
+240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,
+197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,
+150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,
+161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,
+100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,
+18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,
+72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,
+46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,
+117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,
+178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,
+173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,
+117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,
+131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,
+102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,
+162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,
+192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,
+200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,
+117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,
+95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,
+89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,
+98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,
+165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,
+19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,
+160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,
+71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,118,105,160,
+0,0,0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,
+228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,
+131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,
+89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,
+208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,
+202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,
+152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,
+227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,
+192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,
+137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,
+159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,
+79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,
+13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,
+71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,
+77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,
+165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,
+3,192,252,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,
+103,0,0,3,192,252,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,
+140,35,103,0,0,3,192,252,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,
+162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,
+29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,36,35,208,226,100,150,211,
+201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,52,35,208,226,100,150,
+211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,68,35,208,226,100,
+150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,84,35,208,226,
+100,150,211,201,29,162,44,140,35,103,0,0,0,129,0,0,0,0,0,195,154,99,16,38,
+36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,
+162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,
+162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,
+58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,
+237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,
+77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,
+40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,
+89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,
+125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,
+213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,
+216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,
+122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,
+40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,
+148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,
+157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,
+146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,
+173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,
+38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,
+166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,
+217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,
+13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,
+80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,
+201,185,129,4,2,8,3,132,64,60,36,0,171,240,84,6,149,113,72,176,157,91,116,
+116,32,88,181,129,32,11,42,218,221,131,234,219,165,1,8,187,152,255,188,231,
+235,248,47,86,227,105,18,2,56,175,185,255,244,17,91,40,110,173,198,209,208,
+36,7,188,189,179,240,238,82,97,80,93,122,32,125,144,132,160,12,22,162,42,7,
+236,161,25,232,237,105,64,158,160,230,63,205,59,127,102,11,217,66,51,210,
+129,61,65,236,127,154,118,254,205,171,197,34,168,48,6,90,162,1,0,39,75,84,
+72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,
+128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,
+234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,
+91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,
+212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,
+168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,
+192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,
+113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,
+1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,
+147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,
+188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,
+14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,
+35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,
+28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,
+209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,
+201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,
+221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,
+250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,
+131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,
+75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,
+160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,
+108,224,0,0,120,31,128,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,
+145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,33,184,0,0,
+181,32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,
+104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,120,145,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,161,8,244,56,153,37,180,
+242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,177,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,193,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,209,8,244,56,
+153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,225,8,244,
+56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,0,
+97,57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,
+169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,
+211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,
+84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,
+226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,
+30,224,32,54,186,221,128,60,
};
#else
#error invalid endianness defines
@@ -13445,7 +13486,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, d
duk_hstring *h_str;
duk_tval *tv;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_GET_STRING(thr, stridx));
+ tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);
if (tv != NULL && DUK_TVAL_IS_STRING(tv)) {
h_str = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h_str != NULL);
@@ -13462,7 +13503,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, d
DUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {
duk_tval *tv;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_GET_STRING(thr, stridx));
+ tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);
if (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h_buf;
h_buf = DUK_TVAL_GET_BUFFER(tv);
@@ -13481,7 +13522,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, d
duk_tval *tv;
duk_uint32_t val;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_GET_STRING(thr, stridx));
+ tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);
if (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) {
val = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);
} else {
@@ -13493,16 +13534,12 @@ DUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, d
}
DUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {
- duk_tval *tv;
+ duk_hobject *h;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
- if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {
- duk_hobject *h;
+ h = duk_hobject_get_varmap(thr, (duk_hobject *) func);
+ if (h != NULL) {
duk_uint_fast32_t i;
- h = DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(h != NULL);
-
/* We know _Varmap only has own properties so walk property
* table directly. We also know _Varmap is dense and all
* values are numbers; assert for these. GC and finalizers
@@ -13539,11 +13576,10 @@ DUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bu
}
DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {
- duk_tval *tv;
+ duk_harray *h;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_STRING_INT_FORMALS(thr));
- if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {
- duk_harray *h;
+ h = duk_hobject_get_formals(thr, (duk_hobject *) func);
+ if (h != NULL) {
duk_uint32_t i;
/* Here we rely on _Formals being a dense array containing
@@ -13551,10 +13587,6 @@ DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_b
* tweaked by the application (which we don't support right
* now).
*/
- h = (duk_harray *) DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(h != NULL);
- DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));
- DUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_ASSERT(h->length != DUK__NO_FORMALS); /* limits */
@@ -13821,6 +13853,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj));
DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj));
DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj));
+ DUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj));
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj));
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj));
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));
@@ -13952,7 +13985,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT(new_env->thread == NULL); /* Closed. */
DUK_ASSERT(new_env->varmap == NULL);
DUK_ASSERT(new_env->regbase_byteoff == 0);
- DUK_ASSERT_HDECENV_VALID(new_env);
+ DUK_HDECENV_ASSERT_VALID(new_env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);
DUK_HOBJECT_INCREF(thr, func_env);
@@ -13985,9 +14018,11 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
if (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {
/* Restore empty external .prototype only for constructable
- * functions.
+ * functions. The prototype object should inherit from
+ * Object.prototype.
*/
duk_push_object(thr);
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
duk_dup_m2(thr);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */
duk_compact_m1(thr);
@@ -13999,7 +14034,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);
#endif /* DUK_USE_PC2LINE */
- duk_push_object(thr); /* _Varmap */
+ duk_push_bare_object(thr); /* _Varmap */
for (;;) {
/* XXX: awkward */
p = duk__load_string_raw(thr, p);
@@ -14019,7 +14054,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
*/
arr_limit = DUK_RAW_READ_U32_BE(p);
if (arr_limit != DUK__NO_FORMALS) {
- duk_push_array(thr); /* _Formals */
+ duk_push_bare_array(thr); /* _Formals */
for (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {
p = duk__load_string_raw(thr, p);
duk_put_prop_index(thr, -2, arr_idx);
@@ -14214,7 +14249,7 @@ DUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx
* May currently throw an error e.g. when getting the property.
*/
DUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(nargs >= 0);
DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld",
@@ -14230,18 +14265,16 @@ DUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_
#if defined(DUK_USE_VERBOSE_ERRORS)
if (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {
- duk_tval *tv_targ;
duk_tval *tv_base;
duk_tval *tv_key;
- tv_targ = DUK_GET_TVAL_NEGIDX(thr, -1);
+ /* tv_targ is passed on stack top (at index -1). */
tv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);
tv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);
- DUK_ASSERT(tv_targ >= thr->valstack_bottom && tv_targ < thr->valstack_top);
DUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);
DUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);
- duk_call_setup_propcall_error(thr, tv_targ, tv_base, tv_key);
+ duk_call_setup_propcall_error(thr, tv_base, tv_key);
}
#endif
@@ -14311,7 +14344,7 @@ DUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {
duk_idx_t idx_func;
duk_int_t ret;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(udata != NULL);
args = (duk__pcall_args *) udata;
@@ -14347,7 +14380,7 @@ DUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {
duk_idx_t idx_func;
duk_int_t ret;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(udata != NULL);
args = (duk__pcall_method_args *) udata;
@@ -14388,7 +14421,7 @@ DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {
duk_idx_t obj_idx;
duk_int_t ret;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(udata != NULL);
args = (duk__pcall_prop_args *) udata;
@@ -14514,10 +14547,7 @@ DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {
return 0;
}
-/* XXX: Make this obsolete by adding a function flag for rejecting a
- * non-constructor call automatically?
- */
-DUK_INTERNAL void duk_require_constructor_call(duk_hthread *thr) {
+DUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) {
DUK_ASSERT_API_ENTRY(thr);
if (!duk_is_constructor_call(thr)) {
@@ -14623,7 +14653,7 @@ DUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic
DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {
duk_tval *tv;
- DUK_ASSERT_HTHREAD_VALID(thr);
+ DUK_HTHREAD_ASSERT_VALID(thr);
tv = DUK_GET_TVAL_NEGIDX(thr, -1);
if (DUK_TVAL_IS_OBJECT(tv)) {
@@ -14668,23 +14698,34 @@ DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {
/* Shared handling for encode/decode argument. Fast path handling for
* buffer and string values because they're the most common. In particular,
- * avoid creating a temporary string or buffer when possible.
+ * avoid creating a temporary string or buffer when possible. Return value
+ * is guaranteed to be non-NULL, even for zero length input.
*/
DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
- void *ptr;
+ const void *def_ptr = (const void *) out_len; /* Any non-NULL pointer will do. */
+ const void *ptr;
duk_bool_t isbuffer;
+ DUK_ASSERT(out_len != NULL);
+ DUK_ASSERT(def_ptr != NULL);
DUK_ASSERT(duk_is_valid_index(thr, idx)); /* checked by caller */
- /* XXX: with def_ptr set to a stack related pointer, isbuffer could
- * be removed from the helper?
- */
- ptr = duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);
+ ptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);
if (isbuffer) {
- DUK_ASSERT(*out_len == 0 || ptr != NULL);
- return (const duk_uint8_t *) ptr;
+ DUK_ASSERT(ptr != NULL || *out_len == 0U);
+ if (DUK_UNLIKELY(ptr == NULL)) {
+ ptr = def_ptr;
+ }
+ DUK_ASSERT(ptr != NULL);
+ } else {
+ /* For strings a non-NULL pointer is always guaranteed because
+ * at least a NUL will be present.
+ */
+ ptr = (const void *) duk_to_lstring(thr, idx, out_len);
+ DUK_ASSERT(ptr != NULL);
}
- return (const duk_uint8_t *) duk_to_lstring(thr, idx, out_len);
+ DUK_ASSERT(ptr != NULL);
+ return (const duk_uint8_t *) ptr;
}
/*
@@ -14928,6 +14969,8 @@ DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_
const duk_uint8_t *p_end_safe;
duk_uint8_t *q;
+ DUK_ASSERT(src != NULL); /* Required by pointer arithmetic below, which fails for NULL. */
+
p = src;
p_end = src + srclen;
p_end_safe = p_end - 8; /* If 'src <= src_end_safe', safe to read 8 bytes. */
@@ -15263,7 +15306,7 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
idx = duk_require_normalize_index(thr, idx);
src = duk__prep_codec_arg(thr, idx, &srclen);
- /* Note: for srclen=0, src may be NULL */
+ DUK_ASSERT(src != NULL);
/* Compute exact output length. Computation must not wrap; this
* limit works for 32-bit size_t:
@@ -15299,6 +15342,7 @@ DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
idx = duk_require_normalize_index(thr, idx);
src = duk__prep_codec_arg(thr, idx, &srclen);
+ DUK_ASSERT(src != NULL);
/* Round up and add safety margin. Avoid addition before division to
* avoid possibility of wrapping. Margin includes +3 for rounding up,
@@ -15358,7 +15402,7 @@ DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {
idx = duk_require_normalize_index(thr, idx);
inp = duk__prep_codec_arg(thr, idx, &len);
- DUK_ASSERT(inp != NULL || len == 0);
+ DUK_ASSERT(inp != NULL);
/* Fixed buffer, no zeroing because we'll fill all the data. */
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);
@@ -15415,7 +15459,7 @@ DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
idx = duk_require_normalize_index(thr, idx);
inp = duk__prep_codec_arg(thr, idx, &len);
- DUK_ASSERT(inp != NULL || len == 0);
+ DUK_ASSERT(inp != NULL);
if (len & 0x01) {
goto type_error;
@@ -15490,7 +15534,7 @@ DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {
DUK_UNREF(idx);
DUK_ERROR_UNSUPPORTED(thr);
- DUK_WO_NORETURN(return;);
+ DUK_WO_NORETURN(return NULL;);
}
DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
DUK_UNREF(idx);
@@ -15626,7 +15670,7 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {
duk_uint_t flags;
duk_hcompfunc *h_templ;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(udata != NULL);
/* Note: strictness is not inherited from the current Duktape/C
@@ -15754,7 +15798,7 @@ DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {
*/
top = duk_get_top(thr);
- duk_push_array(thr);
+ duk_push_bare_array(thr);
for (idx = 0; idx < top; idx++) {
duk_dup(thr, idx);
duk_put_prop_index(thr, -2, (duk_uarridx_t) idx);
@@ -16637,6 +16681,57 @@ DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t
return duk_to_boolean_top_pop(thr);
}
+/* This get variant is for internal use, it differs from standard
+ * duk_get_prop() in that:
+ * - Object argument must be an object (primitive values not supported).
+ * - Key argument must be a string (no coercion).
+ * - Only own properties are checked (no inheritance). Only "entry part"
+ * properties are checked (not array index properties).
+ * - Property must be a plain data property, not a getter.
+ * - Proxy traps are not triggered.
+ */
+DUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) {
+ duk_hobject *h_obj;
+ duk_hstring *h_key;
+ duk_tval *tv_val;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ /* Note: copying tv_obj and tv_key to locals to shield against a valstack
+ * resize is not necessary for a property get right now.
+ */
+
+ h_obj = duk_get_hobject(thr, obj_idx);
+ if (h_obj == NULL) {
+ return 0;
+ }
+ h_key = duk_require_hstring(thr, -1);
+
+ tv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key);
+ if (tv_val == NULL) {
+ return 0;
+ }
+
+ duk_push_tval(thr, tv_val);
+ duk_remove_m2(thr); /* remove key */
+
+ return 1;
+}
+
+DUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT_STRIDX_VALID(stridx);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ (void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ return duk_xget_owndataprop(thr, obj_idx);
+}
+
+DUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ return duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
+ (duk_small_uint_t) (packed_args & 0xffffUL));
+}
+
DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {
duk_tval *tv_obj;
duk_tval *tv_key;
@@ -17094,9 +17189,6 @@ DUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t f
/*
* Object related
- *
- * Note: seal() and freeze() are accessible through ECMAScript bindings,
- * and are not exposed through the API.
*/
DUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {
@@ -17430,6 +17522,37 @@ DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {
duk_pop(thr);
}
+DUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *obj;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ obj = duk_require_hobject(thr, idx);
+ DUK_ASSERT(obj != NULL);
+
+#if defined(DUK_USE_ROM_OBJECTS)
+ if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
+ DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); /* XXX: "read only object"? */
+ DUK_WO_NORETURN(return;);
+ }
+#endif
+
+ DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL);
+}
+
+DUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *obj;
+ duk_hobject *proto;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ obj = duk_require_hobject(thr, idx);
+ DUK_ASSERT(obj != NULL);
+
+ proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);
+ return (proto == NULL);
+}
+
/*
* Object finalizer
*/
@@ -17443,6 +17566,10 @@ DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {
DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
+ /* This get intentionally walks the inheritance chain at present,
+ * which matches how the effective finalizer property is also
+ * looked up in GC.
+ */
duk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);
}
@@ -17454,6 +17581,12 @@ DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {
h = duk_require_hobject(thr, idx); /* Get before 'put' so that 'idx' is correct. */
callable = duk_is_callable(thr, -1);
+
+ /* At present finalizer is stored as a hidden Symbol, with normal
+ * inheritance and access control. As a result, finalizer cannot
+ * currently be set on a non-extensible (sealed or frozen) object.
+ * It might be useful to allow it.
+ */
duk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);
/* In addition to setting the finalizer property, keep a "have
@@ -18185,7 +18318,7 @@ DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr
duk_tval *tv_prev_alloc_end;
duk_tval *p;
- DUK_ASSERT_HTHREAD_VALID(thr);
+ DUK_HTHREAD_ASSERT_VALID(thr);
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
@@ -18859,8 +18992,8 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr,
/* XXX: several pointer comparison issues here */
DUK_ASSERT_API_ENTRY(to_thr);
- DUK_ASSERT_CTX_VALID(to_thr);
- DUK_ASSERT_CTX_VALID(from_thr);
+ DUK_CTX_ASSERT_VALID(to_thr);
+ DUK_CTX_ASSERT_VALID(from_thr);
DUK_ASSERT(to_thr->heap == from_thr->heap);
if (DUK_UNLIKELY(to_thr == from_thr)) {
@@ -18986,7 +19119,7 @@ DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, du
duk_bool_t ret;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
@@ -19044,7 +19177,7 @@ DUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, d
duk_double_union ret;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
@@ -19329,7 +19462,7 @@ DUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_
duk_tval *tv;
void *p;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
@@ -19404,7 +19537,7 @@ DUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size
duk_size_t len;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
if (out_size != NULL) {
*out_size = 0;
@@ -19503,7 +19636,7 @@ DUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_
* duk_hbufobj, get a validated buffer pointer/length.
*/
duk_hbufobj *h_bufobj = (duk_hbufobj *) h;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
if (h_bufobj->buf != NULL &&
DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {
@@ -19566,7 +19699,7 @@ DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t i
duk_tval *tv;
duk_heaphdr *ret;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
@@ -19801,7 +19934,7 @@ DUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {
}
}
-DUK_INTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {
+DUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *h;
DUK_ASSERT_API_ENTRY(thr);
@@ -19910,7 +20043,7 @@ DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_i
duk_uint_t val_mask;
duk_hobject *res;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
res = duk_get_hobject(thr, idx); /* common case, not promoted */
if (DUK_LIKELY(res != NULL)) {
@@ -20086,7 +20219,7 @@ DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_heaphdr *h;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
if (idx < 0) {
tv = thr->valstack_top + idx;
} else {
@@ -20388,7 +20521,7 @@ DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx,
duk_tval *tv;
duk_double_t d;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
@@ -20526,10 +20659,10 @@ DUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_siz
}
DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_UNREF(udata);
- duk_to_string(thr, -1);
+ (void) duk_to_string(thr, -1);
return 1;
}
@@ -20566,6 +20699,60 @@ DUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, du
return duk_get_lstring(thr, idx, out_len);
}
+DUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ idx = duk_require_normalize_index(thr, idx);
+
+ /* The expected argument to the call is an Error object. The stack
+ * trace is extracted without an inheritance-based instanceof check
+ * so that one can also extract the stack trace of a foreign error
+ * created in another Realm. Accept only a string .stack property.
+ */
+ if (duk_is_object(thr, idx)) {
+ (void) duk_get_prop_string(thr, idx, "stack");
+ if (duk_is_string(thr, -1)) {
+ duk_replace(thr, idx);
+ } else {
+ duk_pop(thr);
+ }
+ }
+
+ return duk_to_string(thr, idx);
+}
+
+DUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) {
+ DUK_CTX_ASSERT_VALID(thr);
+ DUK_UNREF(udata);
+
+ (void) duk_to_stacktrace(thr, -1);
+
+ return 1;
+}
+
+DUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {
+ duk_int_t rc;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ idx = duk_require_normalize_index(thr, idx);
+
+ duk_dup(thr, idx);
+ rc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
+ if (rc != 0) {
+ /* Coercion failed. Try to coerce the coercion itself error
+ * to a stack trace once. If that also fails, return a fixed,
+ * preallocated 'Error' string to avoid potential infinite loop.
+ */
+ rc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
+ if (rc != 0) {
+ duk_pop_unsafe(thr);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);
+ }
+ }
+ duk_replace(thr, idx);
+
+ return duk_get_string(thr, idx);
+}
+
DUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
@@ -22218,7 +22405,7 @@ DUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {
/* XXX: size optimize */
DUK_LOCAL void duk__push_stash(duk_hthread *thr) {
- if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {
+ if (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {
DUK_DDD(DUK_DDDPRINT("creating heap/global/thread stash on first use"));
duk_pop_unsafe(thr);
duk_push_bare_object(thr);
@@ -22257,7 +22444,7 @@ DUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_th
DUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {
duk_int_t len;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_UNREF(thr);
/* NUL terminator handling doesn't matter here */
@@ -22434,6 +22621,33 @@ DUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {
return ret;
}
+DUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) {
+ duk_uint_t flags;
+ duk_harray *obj;
+ duk_idx_t ret;
+ duk_tval *tv_slot;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_FASTREFS |
+ DUK_HOBJECT_FLAG_ARRAY_PART |
+ DUK_HOBJECT_FLAG_EXOTIC_ARRAY |
+ DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);
+
+ obj = duk_harray_alloc(thr, flags);
+ DUK_ASSERT(obj != NULL);
+
+ tv_slot = thr->valstack_top;
+ DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);
+ DUK_HOBJECT_INCREF(thr, obj); /* XXX: could preallocate with refcount = 1 */
+ ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
+ thr->valstack_top++;
+
+ DUK_ASSERT(obj->length == 0); /* Array .length starts at zero. */
+ return ret;
+}
+
DUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {
/* XXX: API call could do this directly, cast to void in API macro. */
duk_harray *a;
@@ -22607,7 +22821,7 @@ DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function fu
duk_tval *tv_slot;
duk_int16_t func_nargs;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK__CHECK_SPACE();
@@ -22752,7 +22966,7 @@ DUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobje
DUK_ASSERT(obj != NULL);
DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);
- DUK_ASSERT_HBUFOBJ_VALID(obj);
+ DUK_HBUFOBJ_ASSERT_VALID(obj);
tv_slot = thr->valstack_top;
DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);
@@ -22826,7 +23040,7 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer,
DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER /* argument is ArrayBuffer */) {
duk_uint_t tmp_offset;
- DUK_ASSERT_HBUFOBJ_VALID((duk_hbufobj *) h_arraybuf);
+ DUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf);
h_val = ((duk_hbufobj *) h_arraybuf)->buf;
if (DUK_UNLIKELY(h_val == NULL)) {
goto arg_error;
@@ -22875,7 +23089,7 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer,
h_bufobj->shift = (tmp >> 4) & 0x0f;
h_bufobj->elem_type = (tmp >> 8) & 0xff;
h_bufobj->is_typedarray = tmp & 0x0f;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
/* TypedArray views need an automatic ArrayBuffer which must be
* provided as .buffer property of the view. The ArrayBuffer is
@@ -23113,7 +23327,7 @@ DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags)
h_proxy->target = h_target;
DUK_ASSERT(h_handler != NULL);
h_proxy->handler = h_handler;
- DUK_ASSERT_HPROXY_VALID(h_proxy);
+ DUK_HPROXY_ASSERT_VALID(h_proxy);
DUK_ASSERT(duk_get_hobject(thr, -2) == h_target);
DUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);
@@ -23267,7 +23481,7 @@ DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {
return ret;
}
- DUK_ASSERT_HEAPHDR_VALID((duk_heaphdr *) ptr);
+ DUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr);
/* If the argument is on finalize_list it has technically been
* unreachable before duk_push_heapptr() but it's still safe to
@@ -23402,7 +23616,7 @@ DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx
duk_tval *tv_end;
#endif
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(count >= 0);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);
@@ -23503,7 +23717,7 @@ DUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {
DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);
@@ -23585,7 +23799,7 @@ DUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {
DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);
@@ -23656,6 +23870,7 @@ DUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {
*/
/* XXX: pack index range? array index offset? */
+/* XXX: need ability to pack into a bare array? */
DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {
duk_tval *tv_src;
duk_tval *tv_dst;
@@ -23684,6 +23899,7 @@ DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {
tv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count); /* XXX: uninitialized would be OK */
DUK_ASSERT(count == 0 || tv_dst != NULL);
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
/* Copy value stack values directly to the array part without
* any refcount updates: net refcount changes are zero.
@@ -23914,7 +24130,7 @@ DUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_c
const char *filename;
duk_int_t line;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
filename = duk_api_global_filename;
line = duk_api_global_line;
@@ -24152,7 +24368,7 @@ DUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring
duk_ucodepoint_t cp;
duk_small_uint_t nchars;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(h_input != NULL);
DUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);
@@ -24196,7 +24412,7 @@ DUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring
}
DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
/* 'tv' may be NULL */
if (tv == NULL) {
@@ -24234,7 +24450,7 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval
* but traverse inheritance chain.
*/
duk_tval *tv_msg;
- tv_msg = duk_hobject_find_existing_entry_tval_ptr(thr->heap, h, DUK_HTHREAD_STRING_MESSAGE(thr));
+ tv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE);
if (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {
/* It's critical to avoid recursion so
* only summarize a string .message.
@@ -24382,7 +24598,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in,
duk_hstring *h;
duk_uint8_t *buf;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
if (DUK_UNLIKELY(count_in <= 0)) {
if (count_in < 0) {
@@ -24919,7 +25135,7 @@ DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {
/* XXX: push more directly? */
(void) duk_push_this_coercible_to_object(thr);
- DUK_ASSERT_HOBJECT_VALID(duk_get_hobject(thr, -1));
+ DUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1));
duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);
len = duk_to_uint32(thr, -1);
@@ -25023,6 +25239,7 @@ DUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {
len_prealloc = len < 64 ? len : 64;
a = duk_push_harray_with_size(thr, len_prealloc);
DUK_ASSERT(a != NULL);
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
a->length = len;
return 1;
}
@@ -26544,7 +26761,7 @@ DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr
DUK_ASSERT(h != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_boolean(thr, -1));
goto type_ok;
}
@@ -26704,7 +26921,7 @@ DUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {
duk_push_this(thr);
DUK_ASSERT(duk_is_buffer(thr, -1));
res = (duk_hbufobj *) duk_to_hobject(thr, -1);
- DUK_ASSERT_HBUFOBJ_VALID(res);
+ DUK_HBUFOBJ_ASSERT_VALID(res);
DUK_DD(DUK_DDPRINT("promoted 'this' automatically to an ArrayBuffer: %!iT", duk_get_tval(thr, -1)));
tv_dst = duk_get_borrowed_this_tval(thr);
@@ -26734,7 +26951,7 @@ DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_u
h_this = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h_this != NULL);
if (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_this)) {
- DUK_ASSERT_HBUFOBJ_VALID(h_this);
+ DUK_HBUFOBJ_ASSERT_VALID(h_this);
return (duk_heaphdr *) h_this;
}
} else if (DUK_TVAL_IS_BUFFER(tv)) {
@@ -26748,7 +26965,7 @@ DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_u
/* XXX: make this conditional to a flag if call sites need it? */
h_this = duk__hbufobj_promote_this(thr);
DUK_ASSERT(h_this != NULL);
- DUK_ASSERT_HBUFOBJ_VALID(h_this);
+ DUK_HBUFOBJ_ASSERT_VALID(h_this);
return (duk_heaphdr *) h_this;
} else {
/* XXX: ugly, share return pointer for duk_hbuffer. */
@@ -26789,13 +27006,13 @@ DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx
h_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h_obj != NULL);
if (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_obj)) {
- DUK_ASSERT_HBUFOBJ_VALID(h_obj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_obj);
return h_obj;
}
} else if (DUK_TVAL_IS_BUFFER(tv)) {
h_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);
DUK_ASSERT(h_obj != NULL);
- DUK_ASSERT_HBUFOBJ_VALID(h_obj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_obj);
return h_obj;
}
@@ -26808,7 +27025,7 @@ DUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, d
DUK_ASSERT(h_bufobj != NULL);
DUK_ASSERT(h_bufobj->buf == NULL); /* no need to decref */
DUK_ASSERT(h_val != NULL);
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
DUK_UNREF(thr);
h_bufobj->buf = h_val;
@@ -26818,7 +27035,7 @@ DUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, d
DUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);
DUK_ASSERT(h_bufobj->is_typedarray == 0);
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
}
/* Shared offset/length coercion helper. */
@@ -27002,7 +27219,7 @@ DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_h
DUK_ASSERT(h_bufobj != NULL);
duk__set_bufobj_buffer(thr, h_bufobj, h_buf);
h_bufobj->is_typedarray = 1;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
h_arrbuf = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
@@ -27012,7 +27229,7 @@ DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_h
DUK_ASSERT(h_arrbuf != NULL);
duk__set_bufobj_buffer(thr, h_arrbuf, h_buf);
DUK_ASSERT(h_arrbuf->is_typedarray == 0);
- DUK_ASSERT_HBUFOBJ_VALID(h_arrbuf);
+ DUK_HBUFOBJ_ASSERT_VALID(h_arrbuf);
DUK_ASSERT(h_bufobj->buf_prop == NULL);
h_bufobj->buf_prop = (duk_hobject *) h_arrbuf;
@@ -27231,7 +27448,7 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {
duk_hbuffer *h_val;
duk_int_t len;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
duk_require_constructor_call(thr);
@@ -27250,7 +27467,7 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {
DUK_ASSERT(h_bufobj != NULL);
duk__set_bufobj_buffer(thr, h_bufobj, h_val);
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
return 1;
@@ -27401,7 +27618,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
h_bufobj->shift = (duk_uint8_t) shift;
h_bufobj->elem_type = (duk_uint8_t) elem_type;
h_bufobj->is_typedarray = 1;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
/* Set .buffer to the argument ArrayBuffer. */
DUK_ASSERT(h_bufobj->buf_prop == NULL);
@@ -27416,7 +27633,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
*/
h_bufarg = (duk_hbufobj *) h_obj;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufarg);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufarg);
elem_length_signed = (duk_int_t) (h_bufarg->length >> h_bufarg->shift);
if (h_bufarg->buf == NULL) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -27505,7 +27722,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
h_bufobj->shift = (duk_uint8_t) shift;
h_bufobj->elem_type = (duk_uint8_t) elem_type;
h_bufobj->is_typedarray = 1;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
/* Copy values, the copy method depends on the arguments.
*
@@ -27689,7 +27906,7 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {
DUK_ASSERT(h_bufarg != NULL);
DUK_HBUFOBJ_INCREF(thr, h_bufarg);
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -27777,7 +27994,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {
duk_push_literal(thr, "[object Object]");
return 1;
}
- DUK_ASSERT_HBUFOBJ_VALID(h_this);
+ DUK_HBUFOBJ_ASSERT_VALID(h_this);
/* Ignore encoding for now. */
@@ -27848,6 +28065,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {
/* XXX: uninitialized would be OK */
DUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);
tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length); /* XXX: needs revision with >4G buffers */
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
DUK_ASSERT(h_this->buf != NULL);
buf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);
@@ -28185,7 +28403,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {
h_this = duk__require_bufobj_this(thr);
DUK_ASSERT(h_this != NULL);
- DUK_ASSERT_HBUFOBJ_VALID(h_this);
+ DUK_HBUFOBJ_ASSERT_VALID(h_this);
if (h_this->buf == NULL) {
DUK_DDD(DUK_DDDPRINT("source neutered, skip copy"));
@@ -28240,7 +28458,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {
duk_small_uint_t dst_elem_size;
h_bufarg = (duk_hbufobj *) h_obj;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufarg);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufarg);
if (h_bufarg->buf == NULL) {
DUK_DDD(DUK_DDDPRINT("target neutered, skip copy"));
@@ -28629,7 +28847,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {
}
/* unbalanced stack on purpose */
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -28811,7 +29029,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {
duk__set_bufobj_buffer(thr, h_bufres, h_val);
h_bufres->is_typedarray = 1;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufres);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufres);
duk_pop(thr); /* pop plain buffer, now reachable through h_bufres */
@@ -29392,7 +29610,7 @@ DUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer
DUK_UNREF(h_res);
duk__set_bufobj_buffer(thr, h_res, h_buf);
- DUK_ASSERT_HBUFOBJ_VALID(h_res);
+ DUK_HBUFOBJ_ASSERT_VALID(h_res);
DUK_ASSERT(h_res->buf_prop == NULL);
return h_res;
}
@@ -30418,7 +30636,7 @@ DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk
DUK_WO_NORETURN(return 0.0;);
}
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
d = duk_to_number_m1(thr);
duk_pop(thr);
@@ -30465,9 +30683,13 @@ DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_doub
d = duk_bi_date_get_timeval_from_dparts(dparts, flags);
duk_push_number(thr, d); /* -> [ ... this timeval_new ] */
duk_dup_top(thr); /* -> [ ... this timeval_new timeval_new ] */
- duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE);
- /* stack top: new time value, return 1 to allow tail calls */
+ /* Must force write because e.g. .setYear() must work even when
+ * the Date instance is frozen.
+ */
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
+
+ /* Stack top: new time value, return 1 to allow tail calls. */
return 1;
}
@@ -31236,7 +31458,11 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {
d = duk__timeclip(duk_to_number(thr, 0));
duk_push_number(thr, d);
duk_dup_top(thr);
- duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE); /* -> [ timeval this timeval ] */
+ /* Must force write because .setTime() must work even when
+ * the Date instance is frozen.
+ */
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
+ /* -> [ timeval this timeval ] */
return 1;
}
@@ -31753,7 +31979,6 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
ULARGE_INTEGER tmp2;
ULARGE_INTEGER tmp3;
FILETIME ft1;
- BOOL ret;
/* XXX: handling of timestamps outside Windows supported range.
* How does Windows deal with dates before 1600? Does windows
@@ -31773,8 +31998,7 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
ft1.dwLowDateTime = tmp2.LowPart;
ft1.dwHighDateTime = tmp2.HighPart;
- ret = FileTimeToSystemTime((const FILETIME *) &ft1, &st2);
- if (!ret) {
+ if (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) {
DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0"));
return 0;
}
@@ -31797,7 +32021,6 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_
FILETIME ft2;
ULARGE_INTEGER tmp1;
ULARGE_INTEGER tmp2;
- BOOL ret;
/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows
* but without accounting for daylight savings time. Use this on
@@ -31813,14 +32036,11 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_
ft1.dwLowDateTime = tmp1.LowPart;
ft1.dwHighDateTime = tmp1.HighPart;
- ret = FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2);
- if (!ret) {
+ if (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) {
DUK_D(DUK_DPRINT("FileTimeToLocalFileTime() failed, return tzoffset 0"));
return 0;
}
-
- ret = FileTimeToSystemTime((const FILETIME *) &ft2, &st2);
- if (!ret) {
+ if (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) {
DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0"));
return 0;
}
@@ -32679,7 +32899,7 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t o
DUK_ASSERT_TOP(thr, 0); /* fixed arg count */
duk_push_this(thr);
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);
idx_td = duk_get_top_index(thr);
duk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);
@@ -35547,7 +35767,8 @@ DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {
* "long long" type exists. Could also rely on C99 directly but that
* won't work for older MSVC.
*/
- DUK_SPRINTF((char *) buf, "%lld", (long long) v);
+ /*DUK_SPRINTF((char *) buf, "%lld", (long long) v);*/
+ DUK_SPRINTF((char *) buf, "%"PRIsizet, (size_t) v);
DUK__EMIT_CSTR(js_ctx, (const char *) buf);
}
#endif
@@ -35779,7 +36000,7 @@ DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
if (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {
DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);
@@ -36184,7 +36405,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
/* With JX/JC a bufferobject gets serialized specially. */
duk_hbufobj *h_bufobj;
h_bufobj = (duk_hbufobj *) h;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
duk__enc_bufobj(js_ctx, h_bufobj);
goto pop2_emitted;
}
@@ -36215,7 +36436,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
#endif
case DUK_HOBJECT_CLASS_BOOLEAN: {
DUK_DDD(DUK_DDDPRINT("value is a Boolean/Buffer/Pointer object -> get internal value"));
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
duk_remove_m2(thr);
break;
}
@@ -36492,7 +36713,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
obj = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(obj != NULL);
- DUK_ASSERT_HOBJECT_VALID(obj);
+ DUK_HOBJECT_ASSERT_VALID(obj);
/* Once recursion depth is increased, exit path must decrease
* it (though it's OK to abort the fast path).
@@ -37940,7 +38161,7 @@ DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "number expected");
DUK_WO_NORETURN(return 0.0;);
}
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_number(thr, -1));
DUK_DDD(DUK_DDDPRINT("number object: %!T, internal value: %!T",
(duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
@@ -39057,7 +39278,7 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),
DUK_BIDX_POINTER_PROTOTYPE);
- /* Pointer object internal value is immutable */
+ /* Pointer object internal value is immutable. */
duk_dup_0(thr);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
}
@@ -39089,7 +39310,7 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr
goto type_error;
}
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
} else {
goto type_error;
}
@@ -39161,7 +39382,7 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h
duk_uarridx_t i, len, idx;
duk_propdesc desc;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(h_proxy_target != NULL);
len = (duk_uarridx_t) duk_get_length(thr, -1);
@@ -39512,8 +39733,8 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
magic = duk_get_current_magic(thr);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {
- duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);
- duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);
+ duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);
+ duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);
h_bc = duk_require_hstring(thr, -1);
re_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */
duk_pop(thr);
@@ -39815,7 +40036,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {
goto type_error;
}
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_string(thr, -1));
} else {
goto type_error;
@@ -41222,7 +41443,6 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {
DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {
duk_tval *tv;
- duk_tval tv_val;
duk_hobject *h_obj;
duk_hstring *h_str;
@@ -41236,10 +41456,10 @@ DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg
h_obj = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h_obj != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {
- if (!duk_hobject_get_internal_value(thr->heap, h_obj, &tv_val)) {
+ tv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj);
+ if (tv == NULL) {
return NULL;
}
- tv = &tv_val;
} else {
return NULL;
}
@@ -41455,6 +41675,18 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
duk_pop(thr);
}
+#if 0
+ /* This check would prevent a heap destruction time finalizer from
+ * launching a coroutine, which would ensure that during finalization
+ * 'thr' would always equal heap_thread. Normal runtime finalizers
+ * run with ms_running == 0, i.e. outside mark-and-sweep. See GH-2030.
+ */
+ if (thr->heap->ms_running) {
+ DUK_D(DUK_DPRINT("refuse Duktape.Thread.resume() when ms_running != 0"));
+ goto state_error;
+ }
+#endif
+
/*
* The error object has been augmented with a traceback and other
* info from its creation point -- usually another thread. The
@@ -41723,7 +41955,9 @@ DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {
* %!T tagged value (duk_tval *)
* %!O heap object (duk_heaphdr *)
* %!I decoded bytecode instruction
- * %!C bytecode instruction opcode name (arg is long)
+ * %!X bytecode instruction opcode name (arg is long)
+ * %!C catcher (duk_catcher *)
+ * %!A activation (duk_activation *)
*
* Everything is serialized in a JSON-like manner. The default depth is one
* level, internal prototype is not followed, and internal properties are not
@@ -42527,6 +42761,47 @@ DUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode)
}
}
+DUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {
+ duk_fixedbuffer *fb = st->fb;
+
+ if (duk_fb_is_full(fb)) {
+ return;
+ }
+
+ if (!cat) {
+ duk_fb_put_cstring(fb, "NULL");
+ return;
+ }
+
+ duk_fb_sprintf(fb, "[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]",
+ (void *) cat,
+ (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,
+ (long) cat->idx_base, (unsigned long) cat->flags);
+}
+
+
+DUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {
+ duk_fixedbuffer *fb = st->fb;
+
+ if (duk_fb_is_full(fb)) {
+ return;
+ }
+
+ if (!act) {
+ duk_fb_put_cstring(fb, "NULL");
+ return;
+ }
+
+ /* prev_caller: conditional, omitted on purpose, it's rarely used. */
+ /* prev_line: conditional, omitted on purpose (but would be nice). */
+ duk_fb_sprintf(fb, "[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]",
+ (void *) act,
+ (void *) act->func, (void *) act->parent, (void *) act->var_env,
+ (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,
+ (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,
+ (long) act->flags);
+}
+
DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {
duk_fixedbuffer fb;
const char *p = format;
@@ -42611,10 +42886,18 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
duk_instr_t t = va_arg(ap, duk_instr_t);
duk__print_instr(&st, t);
break;
- } else if (got_exclamation && ch == DUK_ASC_UC_C) {
+ } else if (got_exclamation && ch == DUK_ASC_UC_X) {
long t = va_arg(ap, long);
duk__print_opcode(&st, (duk_small_int_t) t);
break;
+ } else if (got_exclamation && ch == DUK_ASC_UC_C) {
+ duk_catcher *t = va_arg(ap, duk_catcher *);
+ duk__print_catcher(&st, t);
+ break;
+ } else if (got_exclamation && ch == DUK_ASC_UC_A) {
+ duk_activation *t = va_arg(ap, duk_activation *);
+ duk__print_activation(&st, t);
+ break;
} else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) {
char fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH];
duk_size_t fmtlen;
@@ -44276,18 +44559,25 @@ DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {
* - If side effects are possible, add error catching
*/
- duk_push_tval(thr, &act->tv_func);
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VARMAP);
- if (duk_is_object(thr, -1)) {
- duk_enum(thr, -1, 0 /*enum_flags*/);
- while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {
- varname = duk_known_hstring(thr, -1);
-
- duk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);
- /* [ ... func varmap enum key value this ] */
- duk_debug_write_hstring(thr, duk_get_hstring(thr, -3));
- duk_debug_write_tval(thr, duk_get_tval(thr, -2));
- duk_pop_3(thr); /* -> [ ... func varmap enum ] */
+ if (DUK_TVAL_IS_OBJECT(&act->tv_func)) {
+ duk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func);
+ duk_hobject *h_varmap;
+
+ h_varmap = duk_hobject_get_varmap(thr, h_func);
+ if (h_varmap != NULL) {
+ duk_push_hobject(thr, h_varmap);
+ duk_enum(thr, -1, 0 /*enum_flags*/);
+ while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {
+ varname = duk_known_hstring(thr, -1);
+
+ duk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);
+ /* [ ... func varmap enum key value this ] */
+ duk_debug_write_hstring(thr, duk_get_hstring(thr, -3));
+ duk_debug_write_tval(thr, duk_get_tval(thr, -2));
+ duk_pop_3(thr); /* -> [ ... func varmap enum ] */
+ }
+ } else {
+ DUK_D(DUK_DPRINT("varmap missing in GetLocals, ignore"));
}
} else {
DUK_D(DUK_DPRINT("varmap is not an object in GetLocals, ignore"));
@@ -45628,7 +45918,7 @@ DUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {
heap->dbg_state_dirty = 1;
duk_debug_clear_pause_state(heap);
DUK_ASSERT(heap->ms_running == 0); /* debugger can't be triggered within mark-and-sweep */
- heap->ms_running = 1; /* prevent mark-and-sweep, prevent refzero queueing */
+ heap->ms_running = 2; /* prevent mark-and-sweep, prevent refzero queueing */
heap->ms_prevent_count++;
DUK_ASSERT(heap->ms_prevent_count != 0); /* Wrap. */
DUK_ASSERT(heap->heap_thread != NULL);
@@ -45640,7 +45930,7 @@ DUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {
DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);
heap->dbg_state_dirty = 1;
duk_debug_clear_pause_state(heap);
- DUK_ASSERT(heap->ms_running == 1);
+ DUK_ASSERT(heap->ms_running == 2);
DUK_ASSERT(heap->ms_prevent_count > 0);
heap->ms_prevent_count--;
heap->ms_running = 0;
@@ -45761,9 +46051,9 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
DUK_DD(DUK_DDPRINT("error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring"));
return;
}
- tv_hnd = duk_hobject_find_existing_entry_tval_ptr(thr->heap,
- thr->builtins[DUK_BIDX_DUKTAPE],
- DUK_HTHREAD_GET_STRING(thr, stridx_cb));
+ tv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,
+ thr->builtins[DUK_BIDX_DUKTAPE],
+ stridx_cb);
if (tv_hnd == NULL) {
DUK_DD(DUK_DDPRINT("error handler does not exist or is not a plain value: %!T",
(duk_tval *) tv_hnd));
@@ -45862,9 +46152,13 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
arr_size += 2;
}
- /* XXX: uninitialized would be OK */
+ /* XXX: Uninitialized would be OK. Maybe add internal primitive to
+ * push bare duk_harray with size?
+ */
DUK_D(DUK_DPRINT("preallocated _Tracedata to %ld items", (long) arr_size));
tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);
+ duk_clear_prototype(thr, -1);
+ DUK_ASSERT(duk_is_bare_object(thr, -1));
DUK_ASSERT(arr_size == 0 || tv != NULL);
/* Compiler SyntaxErrors (and other errors) come first, and are
@@ -45941,6 +46235,7 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
DUK_ASSERT(a != NULL);
DUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);
DUK_ASSERT(a->length == (duk_uint32_t) arr_size);
+ DUK_ASSERT(duk_is_bare_object(thr, -1));
}
#endif
@@ -46131,9 +46426,9 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
#if defined(DUK_USE_TRACEBACKS)
/* If tracebacks are enabled, the '_Tracedata' property is the only
* thing we need: 'fileName' and 'lineNumber' are virtual properties
- * which use '_Tracedata'.
+ * which use '_Tracedata'. (Check _Tracedata only as own property.)
*/
- if (duk_hobject_hasprop_raw(thr, obj, DUK_HTHREAD_STRING_INT_TRACEDATA(thr))) {
+ if (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) {
DUK_DDD(DUK_DDDPRINT("error value already has a '_Tracedata' property, not modifying it"));
} else {
duk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);
@@ -46800,6 +47095,19 @@ DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {
return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);
}
/*
+ * duk_hbuffer assertion helpers
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_ASSERTIONS)
+
+DUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) {
+ DUK_ASSERT(h != NULL);
+}
+
+#endif /* DUK_USE_ASSERTIONS */
+/*
* duk_hbuffer operations such as resizing and inserting/appending data to
* a dynamic buffer.
*/
@@ -47155,15 +47463,19 @@ DUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {
}
/* Prevent finalize_list processing and mark-and-sweep entirely.
- * Setting ms_running = 1 also prevents refzero handling from moving
- * objects away from the heap_allocated list (the flag name is a bit
- * misleading here).
+ * Setting ms_running != 0 also prevents refzero handling from moving
+ * objects away from the heap_allocated list. The flag name is a bit
+ * misleading here.
+ *
+ * Use a distinct value for ms_running here (== 2) so that assertions
+ * can detect this situation separate from the normal runtime
+ * mark-and-sweep case. This allows better assertions (GH-2030).
*/
DUK_ASSERT(heap->pf_prevent_count == 0);
- heap->pf_prevent_count = 1;
DUK_ASSERT(heap->ms_running == 0);
- heap->ms_running = 1;
DUK_ASSERT(heap->ms_prevent_count == 0);
+ heap->pf_prevent_count = 1;
+ heap->ms_running = 2; /* Use distinguishable value. */
heap->ms_prevent_count = 1; /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */
curr_limit = 0; /* suppress warning, not used */
@@ -47224,9 +47536,9 @@ DUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {
}
}
- DUK_ASSERT(heap->ms_running == 1);
- heap->ms_running = 0;
+ DUK_ASSERT(heap->ms_running == 2);
DUK_ASSERT(heap->pf_prevent_count == 1);
+ heap->ms_running = 0;
heap->pf_prevent_count = 0;
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
@@ -48705,6 +49017,7 @@ DUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) {
DUK_DDD(DUK_DDDPRINT("duk__mark_hstring: %p", (void *) h));
DUK_ASSERT(h);
+ DUK_HSTRING_ASSERT_VALID(h);
/* nothing to process */
}
@@ -48715,6 +49028,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
DUK_DDD(DUK_DDDPRINT("duk__mark_hobject: %p", (void *) h));
DUK_ASSERT(h);
+ DUK_HOBJECT_ASSERT_VALID(h);
/* XXX: use advancing pointers instead of index macros -> faster and smaller? */
@@ -48755,7 +49069,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
duk_tval *tv, *tv_end;
duk_hobject **fn, **fn_end;
- DUK_ASSERT_HCOMPFUNC_VALID(f);
+ DUK_HCOMPFUNC_ASSERT_VALID(f);
/* 'data' is reachable through every compiled function which
* contains a reference.
@@ -48785,30 +49099,30 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
}
} else if (DUK_HOBJECT_IS_DECENV(h)) {
duk_hdecenv *e = (duk_hdecenv *) h;
- DUK_ASSERT_HDECENV_VALID(e);
+ DUK_HDECENV_ASSERT_VALID(e);
duk__mark_heaphdr(heap, (duk_heaphdr *) e->thread);
duk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap);
} else if (DUK_HOBJECT_IS_OBJENV(h)) {
duk_hobjenv *e = (duk_hobjenv *) h;
- DUK_ASSERT_HOBJENV_VALID(e);
+ DUK_HOBJENV_ASSERT_VALID(e);
duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
duk_hbufobj *b = (duk_hbufobj *) h;
- DUK_ASSERT_HBUFOBJ_VALID(b);
+ DUK_HBUFOBJ_ASSERT_VALID(b);
duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);
duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
duk_hboundfunc *f = (duk_hboundfunc *) (void *) h;
- DUK_ASSERT_HBOUNDFUNC_VALID(f);
+ DUK_HBOUNDFUNC_ASSERT_VALID(f);
duk__mark_tval(heap, &f->target);
duk__mark_tval(heap, &f->this_binding);
duk__mark_tvals(heap, f->args, f->nargs);
#if defined(DUK_USE_ES6_PROXY)
} else if (DUK_HOBJECT_IS_PROXY(h)) {
duk_hproxy *p = (duk_hproxy *) h;
- DUK_ASSERT_HPROXY_VALID(p);
+ DUK_HPROXY_ASSERT_VALID(p);
duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);
duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);
#endif /* DUK_USE_ES6_PROXY */
@@ -48817,7 +49131,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
duk_activation *act;
duk_tval *tv;
- DUK_ASSERT_HTHREAD_VALID(t);
+ DUK_HTHREAD_ASSERT_VALID(t);
tv = t->valstack;
while (tv < t->valstack_top) {
@@ -48864,6 +49178,7 @@ DUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {
return;
}
+ DUK_HEAPHDR_ASSERT_VALID(h);
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)
@@ -48918,6 +49233,7 @@ DUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {
if (tv == NULL) {
return;
}
+ DUK_TVAL_ASSERT_VALID(tv);
if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
duk_heaphdr *h;
h = DUK_TVAL_GET_HEAPHDR(tv);
@@ -48930,6 +49246,7 @@ DUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {
DUK_ASSERT(count == 0 || tv != NULL);
while (count-- > 0) {
+ DUK_TVAL_ASSERT_VALID(tv);
if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
duk_heaphdr *h;
h = DUK_TVAL_GET_HEAPHDR(tv);
@@ -49421,8 +49738,8 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_
#if defined(DUK_USE_DOUBLE_LINKED_HEAP)
DUK_HEAPHDR_SET_PREV(heap, curr, prev);
#endif
- DUK_ASSERT_HEAPHDR_LINKS(heap, prev);
- DUK_ASSERT_HEAPHDR_LINKS(heap, curr);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, prev);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, curr);
prev = curr;
}
@@ -49497,7 +49814,7 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_
if (prev != NULL) {
DUK_HEAPHDR_SET_NEXT(heap, prev, NULL);
}
- DUK_ASSERT_HEAPHDR_LINKS(heap, prev);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, prev);
#if defined(DUK_USE_DEBUG)
DUK_D(DUK_DPRINT("mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization",
@@ -49632,67 +49949,19 @@ DUK_LOCAL void duk__compact_objects(duk_heap *heap) {
*/
#if defined(DUK_USE_ASSERTIONS)
-DUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {
- duk_heaphdr *hdr;
+typedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h);
+typedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h);
- hdr = heap->heap_allocated;
- while (hdr) {
- DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(hdr));
- DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));
- DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(hdr));
- /* may have FINALIZED */
- hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
- }
-
-#if defined(DUK_USE_REFERENCE_COUNTING)
- DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */
-#endif
-}
-
-#if defined(DUK_USE_REFERENCE_COUNTING)
-DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {
- duk_heaphdr *hdr = heap->heap_allocated;
- while (hdr) {
- /* Cannot really assert much w.r.t. refcounts now. */
-
- if (DUK_HEAPHDR_GET_REFCOUNT(hdr) == 0 &&
- DUK_HEAPHDR_HAS_FINALIZED(hdr)) {
- /* An object may be in heap_allocated list with a zero
- * refcount if it has just been finalized and is waiting
- * to be collected by the next cycle.
- * (This doesn't currently happen however.)
- */
- } else if (DUK_HEAPHDR_GET_REFCOUNT(hdr) == 0) {
- /* An object may be in heap_allocated list with a zero
- * refcount also if it is a temporary object created
- * during debugger paused state. It will get collected
- * by mark-and-sweep based on its reachability status
- * (presumably not reachable because refcount is 0).
- */
- }
- DUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(hdr) >= 0); /* Unsigned. */
- hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
+DUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) {
+ duk_heaphdr *curr;
+ for (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
+ func(heap, curr);
}
}
-DUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {
- duk_heaphdr *curr;
+DUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) {
duk_uint32_t i;
- for (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
- curr->h_assert_refcount = 0;
- }
-#if defined(DUK_USE_FINALIZER_SUPPORT)
- for (curr = heap->finalize_list; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
- curr->h_assert_refcount = 0;
- }
-#endif
-#if defined(DUK_USE_REFERENCE_COUNTING)
- for (curr = heap->refzero_list; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
- curr->h_assert_refcount = 0;
- }
-#endif
-
for (i = 0; i < heap->st_size; i++) {
duk_hstring *h;
@@ -49702,12 +49971,93 @@ DUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {
h = heap->strtable[i];
#endif
while (h != NULL) {
- ((duk_heaphdr *) h)->h_assert_refcount = 0;
+ func(heap, h);
h = h->hdr.h_next;
}
}
}
+DUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h));
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h));
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h));
+ /* may have FINALIZED */
+}
+DUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {
+ duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb);
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */
+#endif
+ /* XXX: Assertions for finalize_list? */
+}
+
+DUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ DUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h));
+ duk_heaphdr_assert_valid_subclassed(h);
+}
+DUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) {
+ DUK_UNREF(heap);
+ DUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));
+ duk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h);
+}
+DUK_LOCAL void duk__assert_validity(duk_heap *heap) {
+ duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1);
+#if defined(DUK_USE_FINALIZER_SUPPORT)
+ duk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1);
+#endif
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ duk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1);
+#endif
+ duk__assert_walk_strtable(heap, duk__assert_validity_cb2);
+}
+
+#if defined(DUK_USE_REFERENCE_COUNTING)
+DUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) {
+ /* Cannot really assert much w.r.t. refcounts now. */
+
+ DUK_UNREF(heap);
+ if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 &&
+ DUK_HEAPHDR_HAS_FINALIZED(h)) {
+ /* An object may be in heap_allocated list with a zero
+ * refcount if it has just been finalized and is waiting
+ * to be collected by the next cycle.
+ * (This doesn't currently happen however.)
+ */
+ } else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) {
+ /* An object may be in heap_allocated list with a zero
+ * refcount also if it is a temporary object created
+ * during debugger paused state. It will get collected
+ * by mark-and-sweep based on its reachability status
+ * (presumably not reachable because refcount is 0).
+ */
+ }
+ DUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0); /* Unsigned. */
+}
+DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {
+ duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb);
+}
+
+DUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ h->h_assert_refcount = 0;
+}
+DUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {
+ DUK_UNREF(heap);
+ ((duk_heaphdr *) h)->h_assert_refcount = 0;
+}
+DUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {
+ duk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1);
+#if defined(DUK_USE_FINALIZER_SUPPORT)
+ duk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1);
+#endif
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ duk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1);
+#endif
+ duk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2);
+}
+
DUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {
duk_bool_t count_ok;
duk_size_t expect_refc;
@@ -49740,32 +50090,21 @@ DUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {
}
}
+DUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ duk__check_refcount_heaphdr(h);
+}
+DUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {
+ DUK_UNREF(heap);
+ duk__check_refcount_heaphdr((duk_heaphdr *) h);
+}
DUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {
- duk_heaphdr *curr;
- duk_uint32_t i;
-
- for (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
- duk__check_refcount_heaphdr(curr);
- }
+ duk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1);
#if defined(DUK_USE_FINALIZER_SUPPORT)
- for (curr = heap->finalize_list; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {
- duk__check_refcount_heaphdr(curr);
- }
-#endif
-
- for (i = 0; i < heap->st_size; i++) {
- duk_hstring *h;
-
-#if defined(DUK_USE_STRTAB_PTRCOMP)
- h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);
-#else
- h = heap->strtable[i];
+ duk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1);
#endif
- while (h != NULL) {
- duk__check_refcount_heaphdr((duk_heaphdr *) h);
- h = h->hdr.h_next;
- }
- }
+ /* XXX: Assert anything for refzero_list? */
+ duk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2);
}
#endif /* DUK_USE_REFERENCE_COUNTING */
@@ -49836,6 +50175,12 @@ DUK_LOCAL void duk__dump_stats(duk_heap *heap) {
(long) heap->stats_getvar_all));
DUK_D(DUK_DPRINT("stats putvar: all=%ld",
(long) heap->stats_putvar_all));
+ DUK_D(DUK_DPRINT("stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld",
+ (long) heap->stats_envrec_delayedcreate,
+ (long) heap->stats_envrec_create,
+ (long) heap->stats_envrec_newenv,
+ (long) heap->stats_envrec_oldenv,
+ (long) heap->stats_envrec_pushclosure));
}
#endif /* DUK_USE_DEBUG */
@@ -49906,6 +50251,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
DUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));
DUK_ASSERT(heap->ms_recursion_depth == 0);
duk__assert_heaphdr_flags(heap);
+ duk__assert_validity(heap);
#if defined(DUK_USE_REFERENCE_COUNTING)
/* Note: heap->refzero_free_running may be true; a refcount
* finalizer may trigger a mark-and-sweep.
@@ -50012,11 +50358,20 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
*
* The object insertions go to the front of the list, so they do not
* cause an infinite loop (they are not compacted).
+ *
+ * At present compaction is not allowed when mark-and-sweep runs
+ * during error handling because it involves a duk_safe_call()
+ * interfering with error state.
*/
if ((flags & DUK_MS_FLAG_EMERGENCY) &&
!(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) {
- duk__compact_objects(heap);
+ if (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) {
+ DUK_D(DUK_DPRINT("lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction", (long) heap->lj.type));
+ } else {
+ DUK_D(DUK_DPRINT("object compaction"));
+ duk__compact_objects(heap);
+ }
}
/*
@@ -50040,8 +50395,8 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
*/
DUK_ASSERT(heap->ms_prevent_count == 1);
- heap->ms_prevent_count = 0;
DUK_ASSERT(heap->ms_running == 1);
+ heap->ms_prevent_count = 0;
heap->ms_running = 0;
/*
@@ -50053,6 +50408,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
DUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));
DUK_ASSERT(heap->ms_recursion_depth == 0);
duk__assert_heaphdr_flags(heap);
+ duk__assert_validity(heap);
#if defined(DUK_USE_REFERENCE_COUNTING)
/* Note: heap->refzero_free_running may be true; a refcount
* finalizer may trigger a mark-and-sweep.
@@ -50507,8 +50863,8 @@ DUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphd
DUK_HEAPHDR_SET_PREV(heap, hdr, NULL);
#endif
DUK_HEAPHDR_SET_NEXT(heap, hdr, root);
- DUK_ASSERT_HEAPHDR_LINKS(heap, hdr);
- DUK_ASSERT_HEAPHDR_LINKS(heap, root);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, hdr);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, root);
heap->heap_allocated = hdr;
}
@@ -50568,8 +50924,8 @@ DUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr
}
#endif
DUK_HEAPHDR_SET_NEXT(heap, hdr, root);
- DUK_ASSERT_HEAPHDR_LINKS(heap, hdr);
- DUK_ASSERT_HEAPHDR_LINKS(heap, root);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, hdr);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, root);
heap->finalize_list = hdr;
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
@@ -50668,6 +51024,12 @@ DUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {
heap->curr_thread = new_thr; /* may be NULL */
}
#endif /* DUK_USE_INTERRUPT_COUNTER */
+
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) {
+ DUK_ASSERT(heap != NULL);
+}
+#endif
/*
* Reference counting implementation.
*
@@ -50794,7 +51156,7 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
- DUK_ASSERT_HCOMPFUNC_VALID(f);
+ DUK_HCOMPFUNC_ASSERT_VALID(f);
if (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {
tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);
@@ -50824,31 +51186,31 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
DUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f));
} else if (DUK_HOBJECT_IS_DECENV(h)) {
duk_hdecenv *e = (duk_hdecenv *) h;
- DUK_ASSERT_HDECENV_VALID(e);
+ DUK_HDECENV_ASSERT_VALID(e);
DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread);
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap);
} else if (DUK_HOBJECT_IS_OBJENV(h)) {
duk_hobjenv *e = (duk_hobjenv *) h;
- DUK_ASSERT_HOBJENV_VALID(e);
+ DUK_HOBJENV_ASSERT_VALID(e);
DUK_ASSERT(e->target != NULL); /* Required for object environments. */
DUK_HOBJECT_DECREF_NORZ(thr, e->target);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
duk_hbufobj *b = (duk_hbufobj *) h;
- DUK_ASSERT_HBUFOBJ_VALID(b);
+ DUK_HBUFOBJ_ASSERT_VALID(b);
DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
duk_hboundfunc *f = (duk_hboundfunc *) (void *) h;
- DUK_ASSERT_HBOUNDFUNC_VALID(f);
+ DUK_HBOUNDFUNC_ASSERT_VALID(f);
DUK_TVAL_DECREF_NORZ(thr, &f->target);
DUK_TVAL_DECREF_NORZ(thr, &f->this_binding);
duk__decref_tvals_norz(thr, f->args, f->nargs);
#if defined(DUK_USE_ES6_PROXY)
} else if (DUK_HOBJECT_IS_PROXY(h)) {
duk_hproxy *p = (duk_hproxy *) h;
- DUK_ASSERT_HPROXY_VALID(p);
+ DUK_HPROXY_ASSERT_VALID(p);
DUK_HOBJECT_DECREF_NORZ(thr, p->target);
DUK_HOBJECT_DECREF_NORZ(thr, p->handler);
#endif /* DUK_USE_ES6_PROXY */
@@ -50857,7 +51219,7 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
duk_activation *act;
duk_tval *tv;
- DUK_ASSERT_HTHREAD_VALID(t);
+ DUK_HTHREAD_ASSERT_VALID(t);
tv = t->valstack;
while (tv < t->valstack_top) {
@@ -51191,11 +51553,14 @@ DUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuf
DUK_ASSERT(thr->heap != NULL); \
/* When mark-and-sweep runs, heap_thread must exist. */ \
DUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \
- /* When mark-and-sweep runs, the 'thr' argument always matches heap_thread. \
- * This could be used to e.g. suppress check against 'thr' directly (and \
- * knowing it would be heap_thread); not really used now. \
+ /* In normal operation finalizers are executed with ms_running == 0 \
+ * so we should never see ms_running == 1 and thr != heap_thread. \
+ * In heap destruction finalizers are executed with ms_running != 0 \
+ * to e.g. prevent refzero; a special value ms_running == 2 is used \
+ * in that case so it can be distinguished from the normal runtime \
+ * case, and allows a stronger assertion here (GH-2030). \
*/ \
- DUK_ASSERT(thr->heap->ms_running == 0 || thr == thr->heap->heap_thread); \
+ DUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \
/* We may be called when the heap is initializing and we process \
* refzeros normally, but mark-and-sweep and finalizers are prevented \
* if that's the case. \
@@ -51283,6 +51648,7 @@ DUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_
heap = thr->heap;
htype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h);
+ DUK_DDD(DUK_DDDPRINT("ms_running=%ld, heap_thread=%p", (long) thr->heap->ms_running, thr->heap->heap_thread));
DUK__RZ_SUPPRESS_CHECK();
switch (htype) {
@@ -52869,6 +53235,84 @@ DUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) {
#undef DUK__HEAPPTR_ENC16
#undef DUK__STRTAB_U32_MAX_STRLEN
/*
+ * duk_heaphdr assertion helpers
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_ASSERTIONS)
+
+#if defined(DUK_USE_DOUBLE_LINKED_HEAP)
+DUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ if (h != NULL) {
+ duk_heaphdr *h_prev, *h_next;
+ h_prev = DUK_HEAPHDR_GET_PREV(heap, h);
+ h_next = DUK_HEAPHDR_GET_NEXT(heap, h);
+ DUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h));
+ DUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h));
+ }
+}
+#else
+DUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {
+ DUK_UNREF(heap);
+ DUK_UNREF(h);
+}
+#endif
+
+DUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));
+}
+
+/* Assert validity of a heaphdr, including all subclasses. */
+DUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) {
+ switch (DUK_HEAPHDR_GET_TYPE(h)) {
+ case DUK_HTYPE_OBJECT: {
+ duk_hobject *h_obj = (duk_hobject *) h;
+ DUK_HOBJECT_ASSERT_VALID(h_obj);
+ if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {
+ DUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj);
+ } else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {
+ DUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj);
+ } else if (DUK_HOBJECT_IS_DECENV(h_obj)) {
+ DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj);
+ } else if (DUK_HOBJECT_IS_OBJENV(h_obj)) {
+ DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj);
+ } else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+ DUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj);
+#endif
+ } else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {
+ DUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj);
+ } else if (DUK_HOBJECT_IS_PROXY(h_obj)) {
+ DUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj);
+ } else if (DUK_HOBJECT_IS_THREAD(h_obj)) {
+ DUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj);
+ } else {
+ /* Just a plain object. */
+ ;
+ }
+ break;
+ }
+ case DUK_HTYPE_STRING: {
+ duk_hstring *h_str = (duk_hstring *) h;
+ DUK_HSTRING_ASSERT_VALID(h_str);
+ break;
+ }
+ case DUK_HTYPE_BUFFER: {
+ duk_hbuffer *h_buf = (duk_hbuffer *) h;
+ DUK_HBUFFER_ASSERT_VALID(h_buf);
+ break;
+ }
+ default: {
+ DUK_ASSERT(0);
+ }
+ }
+}
+
+#endif /* DUK_USE_ASSERTIONS */
+/*
* Hobject allocation.
*
* Provides primitive allocation functions for all object types (plain object,
@@ -52904,7 +53348,7 @@ DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags,
DUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);
#endif
#endif
- DUK_ASSERT_HEAPHDR_LINKS(heap, &obj->hdr);
+ DUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr);
DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);
/* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal
@@ -53024,7 +53468,7 @@ DUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject
res->buf_prop = NULL;
#endif
- DUK_ASSERT_HBUFOBJ_VALID(res);
+ DUK_HBUFOBJ_ASSERT_VALID(res);
return res;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -53140,6 +53584,133 @@ DUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_f
return res;
}
/*
+ * duk_hobject and subclass assertion helpers
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_ASSERTIONS)
+
+DUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION);
+ DUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) ||
+ (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY ||
+ DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY));
+ /* Object is an Array <=> object has exotic array behavior */
+ DUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) ||
+ (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)));
+}
+
+DUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));
+ DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h));
+}
+
+DUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h));
+ DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) ||
+ (DUK_TVAL_IS_OBJECT(&h->target) &&
+ DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target))));
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding));
+ DUK_ASSERT(h->nargs == 0 || h->args != NULL);
+}
+
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+DUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(h->shift <= 3);
+ DUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX);
+ DUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) ||
+ (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) ||
+ (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) ||
+ (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) ||
+ (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) ||
+ (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) ||
+ (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) ||
+ (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) ||
+ (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64));
+ DUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1);
+ DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h));
+ if (h->buf == NULL) {
+ DUK_ASSERT(h->offset == 0);
+ DUK_ASSERT(h->length == 0);
+ } else {
+ /* No assertions for offset or length; in particular,
+ * it's OK for length to be longer than underlying
+ * buffer. Just ensure they don't wrap when added.
+ */
+ DUK_ASSERT(h->offset + h->length >= h->offset);
+ }
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+
+DUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) {
+ DUK_ASSERT(h != NULL);
+}
+
+DUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) {
+ DUK_ASSERT(h != NULL);
+}
+
+DUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h));
+ DUK_ASSERT(h->thread == NULL || h->varmap != NULL);
+}
+
+DUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h));
+ DUK_ASSERT(h->target != NULL);
+ DUK_ASSERT(h->has_this == 0 || h->has_this == 1);
+}
+
+DUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) {
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(h->target != NULL);
+ DUK_ASSERT(h->handler != NULL);
+ DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h));
+}
+
+DUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) {
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT);
+ DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr));
+ DUK_ASSERT(thr->unused1 == 0);
+ DUK_ASSERT(thr->unused2 == 0);
+}
+
+DUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) {
+ DUK_ASSERT(thr != NULL);
+ DUK_HTHREAD_ASSERT_VALID(thr);
+ DUK_ASSERT(thr->valstack != NULL);
+ DUK_ASSERT(thr->valstack_bottom != NULL);
+ DUK_ASSERT(thr->valstack_top != NULL);
+ DUK_ASSERT(thr->valstack_end != NULL);
+ DUK_ASSERT(thr->valstack_alloc_end != NULL);
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);
+}
+
+#endif /* DUK_USE_ASSERTIONS */
+/*
* Object enumeration support.
*
* Creates an internal enumeration state object to be used e.g. with for-in
@@ -53358,11 +53929,11 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint
* real object to check against.
*/
duk_push_hobject(thr, enum_target);
- duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET); /* Target is bare, plain put OK. */
/* Initialize index so that we skip internal control keys. */
duk_push_int(thr, DUK__ENUM_START_INDEX);
- duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT); /* Target is bare, plain put OK. */
/*
* Proxy object handling
@@ -53396,7 +53967,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint
enum_target = h_proxy_target;
duk_push_hobject(thr, enum_target); /* -> [ ... enum_target res handler undefined target ] */
- duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);
+ duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET); /* Target is bare, plain put OK. */
duk_pop_2(thr); /* -> [ ... enum_target res ] */
goto skip_proxy;
@@ -53450,6 +54021,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint
#if !defined(DUK_USE_PREFER_SIZE)
duk_bool_t need_sort = 0;
#endif
+ duk_bool_t cond;
/* Enumeration proceeds by inheritance level. Virtual
* properties need to be handled specially, followed by
@@ -53476,10 +54048,12 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
- if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr)) {
+ cond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr);
#else
- if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {
+ cond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr);
#endif
+ cond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);
+ if (cond) {
duk_bool_t have_length = 1;
/* String and buffer enumeration behavior is identical now,
@@ -53541,26 +54115,29 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint
* Array part
*/
- for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {
- duk_hstring *k;
- duk_tval *tv;
+ cond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);
+ if (cond) {
+ for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {
+ duk_hstring *k;
+ duk_tval *tv;
- tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
- if (DUK_TVAL_IS_UNUSED(tv)) {
- continue;
- }
- k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i); /* Fragile reachability. */
- DUK_ASSERT(k);
+ tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
+ if (DUK_TVAL_IS_UNUSED(tv)) {
+ continue;
+ }
+ k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i); /* Fragile reachability. */
+ DUK_ASSERT(k);
- duk__add_enum_key(thr, k);
+ duk__add_enum_key(thr, k);
- /* [enum_target res] */
- }
+ /* [enum_target res] */
+ }
- if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {
- /* Array .length comes after numeric indices. */
- if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
- duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);
+ if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {
+ /* Array .length comes after numeric indices. */
+ if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
+ duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);
+ }
}
}
@@ -53717,7 +54294,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t
* be the proxy, and checking key existence against the proxy is not
* required (or sensible, as the keys may be fully virtual).
*/
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);
+ duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);
enum_target = duk_require_hobject(thr, -1);
DUK_ASSERT(enum_target != NULL);
#if defined(DUK_USE_ES6_PROXY)
@@ -53814,6 +54391,7 @@ DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_sma
/* XXX: uninit would be OK */
tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);
DUK_ASSERT(count == 0 || tv != NULL);
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
/* Fill result array, no side effects. */
@@ -54124,7 +54702,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_i
* future work in debugger.rst).
*/
- duk_get_prop_stridx(thr, idx_func, DUK_STRIDX_INT_PC2LINE);
+ duk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE);
pc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);
if (pc2line != NULL) {
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));
@@ -54216,6 +54794,9 @@ DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hob
DUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);
DUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);
+DUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj);
+DUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx);
+
/*
* Misc helpers
*/
@@ -54374,8 +54955,6 @@ DUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {
DUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {
duk_uint32_t res;
- DUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);
-
res = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR;
DUK_ASSERT(res >= 1); /* important for callers */
return res;
@@ -54385,8 +54964,6 @@ DUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {
DUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {
duk_uint32_t res;
- DUK_ASSERT((duk_size_t) a_size <= DUK_HOBJECT_MAX_PROPERTIES);
-
res = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR;
DUK_ASSERT(res >= 1); /* important for callers */
return res;
@@ -54491,6 +55068,105 @@ DUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx
return (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));
}
+DUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {
+ duk_uint32_t min_size;
+ duk_uint32_t old_used;
+ duk_uint32_t old_size;
+
+ if (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) {
+ DUK_DDD(DUK_DDDPRINT("=> fast resize is OK"));
+ return 0;
+ }
+
+ duk__compute_a_stats(thr, obj, &old_used, &old_size);
+
+ DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld",
+ (long) old_used, (long) old_size, (long) arr_idx));
+
+ min_size = arr_idx + 1;
+#if defined(DUK_USE_OBJSIZES16)
+ if (min_size > DUK_UINT16_MAX) {
+ goto do_abandon;
+ }
+#endif
+ DUK_UNREF(min_size);
+
+ /* Note: intentionally use approximations to shave a few instructions:
+ * a_used = old_used (accurate: old_used + 1)
+ * a_size = arr_idx (accurate: arr_idx + 1)
+ */
+ if (duk__abandon_array_density_check(old_used, arr_idx)) {
+ DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
+ "decided to abandon array part (would become too sparse)"));
+
+ /* Abandoning requires a props allocation resize and
+ * 'rechecks' the valstack, invalidating any existing
+ * valstack value pointers.
+ */
+ goto do_abandon;
+ }
+
+ DUK_DDD(DUK_DDDPRINT("=> decided to keep array part"));
+ return 0;
+
+ do_abandon:
+ duk__abandon_array_part(thr, obj);
+ DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ return 1;
+}
+
+DUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {
+ /*
+ * Array needs to grow, but we don't want it becoming too sparse.
+ * If it were to become sparse, abandon array part, moving all
+ * array entries into the entries part (for good).
+ *
+ * Since we don't keep track of actual density (used vs. size) of
+ * the array part, we need to estimate somehow. The check is made
+ * in two parts:
+ *
+ * - Check whether the resize need is small compared to the
+ * current size (relatively); if so, resize without further
+ * checking (essentially we assume that the original part is
+ * "dense" so that the result would be dense enough).
+ *
+ * - Otherwise, compute the resize using an actual density
+ * measurement based on counting the used array entries.
+ */
+
+ DUK_DDD(DUK_DDDPRINT("write to new array requires array resize, decide whether to do a "
+ "fast resize without abandon check (arr_idx=%ld, old_size=%ld)",
+ (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj)));
+
+ if (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) {
+ DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ return NULL;
+ }
+
+ DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
+ "decided to extend current allocation"));
+
+ /* In principle it's possible to run out of memory extending the
+ * array but with the allocation going through if we were to abandon
+ * the array part and try again. In practice this should be rare
+ * because abandoned arrays have a higher per-entry footprint.
+ */
+
+ duk__grow_props_for_array_item(thr, obj, arr_idx);
+
+ DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
+ return DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
+}
+
+DUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {
+ if (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) {
+ return DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
+ } else {
+ return duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj);
+ }
+}
+
/*
* Proxy helpers
*/
@@ -54510,7 +55186,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **
return 0;
}
h_proxy = (duk_hproxy *) obj;
- DUK_ASSERT_HPROXY_VALID(h_proxy);
+ DUK_HPROXY_ASSERT_VALID(h_proxy);
DUK_ASSERT(h_proxy->handler != NULL);
DUK_ASSERT(h_proxy->target != NULL);
@@ -54537,7 +55213,7 @@ DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {
duk_hproxy *h_proxy;
h_proxy = (duk_hproxy *) obj;
- DUK_ASSERT_HPROXY_VALID(h_proxy);
+ DUK_HPROXY_ASSERT_VALID(h_proxy);
obj = h_proxy->target;
DUK_ASSERT(obj != NULL);
}
@@ -54745,6 +55421,16 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
DUK_ERROR_ALLOC_FAILED(thr);
DUK_WO_NORETURN(return;);
}
+#if defined(DUK_USE_OBJSIZES16)
+ if (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) {
+ /* If caller gave us sizes larger than what we can store,
+ * fail memory safely with an internal error rather than
+ * truncating the sizes.
+ */
+ DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return;);
+ }
+#endif
/*
* Compute new alloc size and alloc new area.
@@ -55120,34 +55806,10 @@ DUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,
duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
}
-#if 0 /*unused */
-DUK_INTERNAL void duk_hobject_resize_arraypart(duk_hthread *thr,
- duk_hobject *obj,
- duk_uint32_t new_a_size) {
- duk_uint32_t old_a_size;
- duk_uint32_t new_e_size;
- duk_uint32_t new_h_size;
-
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT(obj != NULL);
-
- if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
- return;
- }
- old_a_size = DUK_HOBJECT_GET_ASIZE(obj);
- if (old_a_size > new_a_size) {
- new_a_size = old_a_size;
- }
- new_e_size = DUK_HOBJECT_GET_ESIZE(obj);
- new_h_size = DUK_HOBJECT_GET_HSIZE(obj);
-
- duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
-}
-#endif
-
/* Grow entry part allocation for one additional entry. */
DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {
duk_uint32_t old_e_used; /* actually used, non-NULL entries */
+ duk_uint32_t new_e_size_minimum;
duk_uint32_t new_e_size;
duk_uint32_t new_a_size;
duk_uint32_t new_h_size;
@@ -55163,6 +55825,7 @@ DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject
*/
old_e_used = duk__count_used_e_keys(thr, obj);
+ new_e_size_minimum = old_e_used + 1;
new_e_size = old_e_used + duk__get_min_grow_e(old_e_used);
#if defined(DUK_USE_HOBJECT_HASH_PART)
new_h_size = duk__get_default_h_size(new_e_size);
@@ -55170,7 +55833,24 @@ DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject
new_h_size = 0;
#endif
new_a_size = DUK_HOBJECT_GET_ASIZE(obj);
- DUK_ASSERT(new_e_size >= old_e_used + 1); /* duk__get_min_grow_e() is always >= 1 */
+
+#if defined(DUK_USE_OBJSIZES16)
+ if (new_e_size > DUK_UINT16_MAX) {
+ new_e_size = DUK_UINT16_MAX;
+ }
+ if (new_h_size > DUK_UINT16_MAX) {
+ new_h_size = DUK_UINT16_MAX;
+ }
+ if (new_a_size > DUK_UINT16_MAX) {
+ new_a_size = DUK_UINT16_MAX;
+ }
+#endif
+ DUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);
+
+ if (!(new_e_size >= new_e_size_minimum)) {
+ DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
+ }
duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
}
@@ -55179,19 +55859,36 @@ DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject
DUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {
duk_uint32_t new_e_size;
duk_uint32_t new_a_size;
+ duk_uint32_t new_a_size_minimum;
duk_uint32_t new_h_size;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));
- /* minimum new length is highest_arr_idx + 1 */
-
new_e_size = DUK_HOBJECT_GET_ESIZE(obj);
new_h_size = DUK_HOBJECT_GET_HSIZE(obj);
+ new_a_size_minimum = highest_arr_idx + 1;
new_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);
DUK_ASSERT(new_a_size >= highest_arr_idx + 1); /* duk__get_min_grow_a() is always >= 1 */
+#if defined(DUK_USE_OBJSIZES16)
+ if (new_e_size > DUK_UINT16_MAX) {
+ new_e_size = DUK_UINT16_MAX;
+ }
+ if (new_h_size > DUK_UINT16_MAX) {
+ new_h_size = DUK_UINT16_MAX;
+ }
+ if (new_a_size > DUK_UINT16_MAX) {
+ new_a_size = DUK_UINT16_MAX;
+ }
+#endif
+
+ if (!(new_a_size >= new_a_size_minimum)) {
+ DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
+ }
+
duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
}
@@ -55200,7 +55897,8 @@ DUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj
* We also compact the entries part while we're at it, although
* this is not strictly required.
*/
-DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj) {
+DUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) {
+ duk_uint32_t new_e_size_minimum;
duk_uint32_t new_e_size;
duk_uint32_t new_a_size;
duk_uint32_t new_h_size;
@@ -55220,8 +55918,8 @@ DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj) {
* of space right away.
*/
- new_e_size = e_used + a_used;
- new_e_size = new_e_size + duk__get_min_grow_e(new_e_size);
+ new_e_size_minimum = e_used + a_used;
+ new_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum);
new_a_size = 0;
#if defined(DUK_USE_HOBJECT_HASH_PART)
new_h_size = duk__get_default_h_size(new_e_size);
@@ -55229,6 +55927,23 @@ DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj) {
new_h_size = 0;
#endif
+#if defined(DUK_USE_OBJSIZES16)
+ if (new_e_size > DUK_UINT16_MAX) {
+ new_e_size = DUK_UINT16_MAX;
+ }
+ if (new_h_size > DUK_UINT16_MAX) {
+ new_h_size = DUK_UINT16_MAX;
+ }
+ if (new_a_size > DUK_UINT16_MAX) {
+ new_a_size = DUK_UINT16_MAX;
+ }
+#endif
+
+ if (!(new_e_size >= new_e_size_minimum)) {
+ DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
+ }
+
DUK_DD(DUK_DDPRINT("abandon array part for hobject %p, "
"array stats before: e_used=%ld, a_used=%ld, a_size=%ld; "
"resize to e_size=%ld, a_size=%ld, h_size=%ld",
@@ -55313,7 +56028,7 @@ DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj)
* but there is no hash part, h_idx is set to -1.
*/
-DUK_INTERNAL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
+DUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
DUK_ASSERT(e_idx != NULL);
@@ -55330,7 +56045,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobj
duk_uint_fast32_t i;
duk_uint_fast32_t n;
duk_hstring **h_keys_base;
- DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using linear scan for lookup"));
+ DUK_DDD(DUK_DDDPRINT("duk_hobject_find_entry() using linear scan for lookup"));
h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);
n = DUK_HOBJECT_GET_ENEXT(obj);
@@ -55351,7 +56066,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobj
duk_uint32_t *h_base;
duk_uint32_t mask;
- DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using hash part for lookup"));
+ DUK_DDD(DUK_DDDPRINT("duk_hobject_find_entry() using hash part for lookup"));
h_base = DUK_HOBJECT_H_GET_BASE(heap, obj);
n = DUK_HOBJECT_GET_HSIZE(obj);
@@ -55397,7 +56112,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobj
}
/* For internal use: get non-accessor entry value */
-DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {
+DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {
duk_int_t e_idx;
duk_int_t h_idx;
@@ -55405,7 +56120,7 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap,
DUK_ASSERT(key != NULL);
DUK_UNREF(heap);
- if (duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx)) {
+ if (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {
DUK_ASSERT(e_idx >= 0);
if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
@@ -55414,8 +56129,12 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap,
return NULL;
}
+DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {
+ return duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx));
+}
+
/* For internal use: get non-accessor entry value and attributes */
-DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {
+DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {
duk_int_t e_idx;
duk_int_t h_idx;
@@ -55424,7 +56143,7 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_he
DUK_ASSERT(out_attrs != NULL);
DUK_UNREF(heap);
- if (duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx)) {
+ if (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {
DUK_ASSERT(e_idx >= 0);
if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
@@ -55436,7 +56155,7 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_he
}
/* For internal use: get array part value */
-DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {
+DUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {
duk_tval *tv;
DUK_ASSERT(obj != NULL);
@@ -55539,47 +56258,67 @@ DUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobje
* to incref OR decref. No proxies or accessors are invoked, no prototype walk.
*/
-DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobject *obj, duk_tval *tv_out) {
- duk_int_t e_idx;
- duk_int_t h_idx;
+DUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) {
+ return duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE);
+}
+
+DUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) {
+ duk_tval *tv;
DUK_ASSERT(heap != NULL);
DUK_ASSERT(obj != NULL);
- DUK_ASSERT(tv_out != NULL);
- /* Always in entry part, no need to look up parents etc. */
- if (duk_hobject_find_existing_entry(heap, obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx, &h_idx)) {
- DUK_ASSERT(e_idx >= 0);
- DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx));
- DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
- return 1;
+ tv = duk_hobject_get_internal_value_tval_ptr(heap, obj);
+ if (tv != NULL) {
+ duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);
+ DUK_ASSERT(h != NULL);
+ return h;
}
- DUK_TVAL_SET_UNDEFINED(tv_out);
- return 0;
+
+ return NULL;
}
DUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {
- duk_tval tv;
+ duk_hstring *h;
- DUK_ASSERT(heap != NULL);
- DUK_ASSERT(obj != NULL);
+ h = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj);
+ if (h != NULL) {
+ DUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));
+ }
+ return h;
+}
- /* This is not strictly necessary, but avoids compiler warnings; e.g.
- * gcc won't reliably detect that no uninitialized data is read below.
- */
- duk_memzero((void *) &tv, sizeof(duk_tval));
+DUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {
+ duk_tval *tv;
+ duk_hobject *h;
- if (duk_hobject_get_internal_value(heap, obj, &tv)) {
- duk_hstring *h;
- DUK_ASSERT(DUK_TVAL_IS_STRING(&tv));
- h = DUK_TVAL_GET_STRING(&tv);
- /* No explicit check for string vs. symbol, accept both. */
+ tv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx);
+ if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
return h;
}
-
return NULL;
}
+DUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) {
+ duk_harray *h;
+
+ h = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS);
+ if (h != NULL) {
+ DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));
+ DUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));
+ }
+ return h;
+}
+
+DUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) {
+ duk_hobject *h;
+
+ h = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP);
+ return h;
+}
+
/*
* Arguments handling helpers (argument map mainly).
*
@@ -55834,7 +56573,7 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
* same keys so the entry part vs. array part order doesn't matter.
*/
- if (duk_hobject_find_existing_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {
+ if (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {
duk_int_t e_idx = out_desc->e_idx;
DUK_ASSERT(out_desc->e_idx >= 0);
out_desc->a_idx = -1;
@@ -55905,7 +56644,7 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
(duk_heaphdr *) key, (long) arr_idx));
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));
@@ -55987,7 +56726,7 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
duk_small_uint_t elem_size;
h_bufobj = (duk_hbufobj *) obj;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
DUK_DDD(DUK_DDDPRINT("bufobj property get for key: %!O, arr_idx: %ld",
(duk_heaphdr *) key, (long) arr_idx));
@@ -56298,7 +57037,7 @@ DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr,
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); /* caller ensures */
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
#if defined(DUK_USE_FASTINT)
if (DUK_TVAL_IS_FASTINT(tv_key)) {
@@ -57388,7 +58127,7 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));
DUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
DUK_ASSERT(duk_is_valid_index(thr, -1));
@@ -57918,7 +58657,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
duk_small_uint_t elem_size;
h_bufobj = (duk_hbufobj *) curr;
- DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
DUK_DD(DUK_DDPRINT("writable virtual property is in buffer object"));
@@ -58090,7 +58829,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
duk_harray *a;
a = (duk_harray *) orig;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
old_len = a->length;
@@ -58130,84 +58869,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
* tv_obj, tv_key, and tv_val are copies of the original inputs.
*/
- if (arr_idx != DUK__NO_ARRAY_INDEX &&
- DUK_HOBJECT_HAS_ARRAY_PART(orig)) {
- if (arr_idx < DUK_HOBJECT_GET_ASIZE(orig)) {
- goto no_array_growth;
- }
-
- /*
- * Array needs to grow, but we don't want it becoming too sparse.
- * If it were to become sparse, abandon array part, moving all
- * array entries into the entries part (for good).
- *
- * Since we don't keep track of actual density (used vs. size) of
- * the array part, we need to estimate somehow. The check is made
- * in two parts:
- *
- * - Check whether the resize need is small compared to the
- * current size (relatively); if so, resize without further
- * checking (essentially we assume that the original part is
- * "dense" so that the result would be dense enough).
- *
- * - Otherwise, compute the resize using an actual density
- * measurement based on counting the used array entries.
- */
-
- DUK_DDD(DUK_DDDPRINT("write to new array requires array resize, decide whether to do a "
- "fast resize without abandon check (arr_idx=%ld, old_size=%ld)",
- (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(orig)));
-
- if (duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(orig))) {
- duk_uint32_t old_used;
- duk_uint32_t old_size;
-
- DUK_DDD(DUK_DDDPRINT("=> fast check is NOT OK, do slow check for array abandon"));
-
- duk__compute_a_stats(thr, orig, &old_used, &old_size);
-
- DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld",
- (long) old_used, (long) old_size, (long) arr_idx));
-
- /* Note: intentionally use approximations to shave a few instructions:
- * a_used = old_used (accurate: old_used + 1)
- * a_size = arr_idx (accurate: arr_idx + 1)
- */
- if (duk__abandon_array_density_check(old_used, arr_idx)) {
- DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
- "decided to abandon array part (would become too sparse)"));
-
- /* abandoning requires a props allocation resize and
- * 'rechecks' the valstack, invalidating any existing
- * valstack value pointers!
- */
- duk__abandon_array_checked(thr, orig);
- DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));
-
- goto write_to_entry_part;
- }
-
- DUK_DDD(DUK_DDDPRINT("=> decided to keep array part"));
- } else {
- DUK_DDD(DUK_DDDPRINT("=> fast resize is OK"));
+ if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) {
+ tv = duk__obtain_arridx_slot(thr, arr_idx, orig);
+ if (tv == NULL) {
+ DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));
+ goto write_to_entry_part;
}
- DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
- "decided to extend current allocation"));
-
- duk__grow_props_for_array_item(thr, orig, arr_idx);
-
- no_array_growth:
-
- /* Note: assume array part is comprehensive, so that either
- * the write goes to the array part, or we've abandoned the
- * array above (and will not come here).
- */
-
- DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(orig));
- DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(orig));
-
- tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, arr_idx);
/* prev value must be unused, no decref */
DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));
DUK_TVAL_SET_TVAL(tv, tv_val);
@@ -58820,8 +59488,8 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
#endif
new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));
((duk_harray *) obj)->length = new_len;
- DUK_D(DUK_DPRINT("internal define property for array .length: %ld -> %ld",
- (long) prev_len, (long) ((duk_harray *) obj)->length));
+ DUK_DD(DUK_DDPRINT("internal define property for array .length: %ld -> %ld",
+ (long) prev_len, (long) ((duk_harray *) obj)->length));
goto pop_exit;
}
DUK_DD(DUK_DDPRINT("property already exists but is virtual -> failure"));
@@ -58836,17 +59504,18 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
DUK_DDD(DUK_DDDPRINT("property does not exist, object has array part -> possibly extend array part and write value (assert attributes)"));
DUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);
- /* always grow the array, no sparse / abandon support here */
- if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
- duk__grow_props_for_array_item(thr, obj, arr_idx);
+ tv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);
+ if (tv1 == NULL) {
+ DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ goto write_to_entry_part;
}
- DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
goto write_value;
}
}
+ write_to_entry_part:
DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes"));
e_idx = duk__hobject_alloc_entry_checked(thr, obj, key); /* increases key refcount */
DUK_ASSERT(e_idx >= 0);
@@ -58903,13 +59572,11 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("define property to array part (property may or may not exist yet)"));
- /* always grow the array, no sparse / abandon support here */
- if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
- duk__grow_props_for_array_item(thr, obj, arr_idx);
+ tv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);
+ if (tv1 == NULL) {
+ DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ goto write_slow;
}
-
- DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
- tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
tv2 = duk_require_tval(thr, -1);
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
@@ -58918,6 +59585,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
return;
}
+ write_slow:
DUK_DDD(DUK_DDDPRINT("define property fast path didn't work, use slow path"));
key = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);
@@ -58936,7 +59604,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {
duk_double_t val;
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(obj != NULL);
/* Fast path for Arrays. */
@@ -59315,7 +59983,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
*/
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
arrlen_old_len = a->length;
DUK_ASSERT(idx_value >= 0);
@@ -59356,7 +60024,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
duk_harray *a;
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
old_len = a->length;
@@ -59446,7 +60114,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
DUK_DDD(DUK_DDDPRINT("accessor cannot go to array part, abandon array"));
- duk__abandon_array_checked(thr, obj);
+ duk__abandon_array_part(thr, obj);
}
/* write to entry part */
@@ -59488,17 +60156,22 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
-#if 0
DUK_DDD(DUK_DDDPRINT("new data property attributes match array defaults, attempt to write to array part"));
- /* may become sparse...*/
-#endif
- /* XXX: handling for array part missing now; this doesn't affect
- * compliance but causes array entry writes using defineProperty()
- * to always abandon array part.
- */
+ tv2 = duk__obtain_arridx_slot(thr, arr_idx, obj);
+ if (tv2 == NULL) {
+ DUK_DDD(DUK_DDDPRINT("failed writing to array part, abandoned array"));
+ } else {
+ DUK_DDD(DUK_DDDPRINT("success in writing to array part"));
+ DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));
+ DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2));
+ DUK_TVAL_SET_TVAL(tv2, &tv);
+ DUK_TVAL_INCREF(thr, tv2);
+ goto success_exotics;
+ }
+ } else {
+ DUK_DDD(DUK_DDDPRINT("new data property cannot go to array part, abandon array"));
+ duk__abandon_array_part(thr, obj);
}
- DUK_DDD(DUK_DDDPRINT("new data property cannot go to array part, abandon array"));
- duk__abandon_array_checked(thr, obj);
/* fall through */
}
@@ -59675,7 +60348,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("convert property to accessor property"));
if (curr.a_idx >= 0) {
DUK_DDD(DUK_DDDPRINT("property to convert is stored in an array entry, abandon array and re-lookup"));
- duk__abandon_array_checked(thr, obj);
+ duk__abandon_array_part(thr, obj);
duk_pop_unsafe(thr); /* remove old value */
rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
DUK_UNREF(rc);
@@ -59831,7 +60504,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
}
DUK_DDD(DUK_DDDPRINT("array index, new property attributes do not match array defaults, abandon array and re-lookup"));
- duk__abandon_array_checked(thr, obj);
+ duk__abandon_array_part(thr, obj);
duk_pop_unsafe(thr); /* remove old value */
rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
DUK_UNREF(rc);
@@ -59857,7 +60530,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
duk_harray *a;
a = (duk_harray *) obj;
DUK_DD(DUK_DDPRINT("Object.defineProperty() attribute update for duk_harray .length -> %02lx", (unsigned long) new_flags));
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
if ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) {
DUK_D(DUK_DPRINT("Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail"));
goto fail_virtual;
@@ -59926,7 +60599,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
duk_harray *a;
a = (duk_harray *) obj;
DUK_DD(DUK_DDPRINT("Object.defineProperty() value update for duk_harray .length -> %ld", (long) arrlen_new_len));
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
a->length = arrlen_new_len;
} else {
goto fail_virtual; /* should not happen */
@@ -59958,7 +60631,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
duk_harray *a;
a = (duk_harray *) obj;
- DUK_ASSERT_HARRAY_VALID(a);
+ DUK_HARRAY_ASSERT_VALID(a);
if (arridx_new_array_length > 0) {
/*
@@ -60152,13 +60825,13 @@ DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_ho
* for the same object; not likely).
*/
- duk__abandon_array_checked(thr, obj);
+ duk__abandon_array_part(thr, obj);
DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);
for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
duk_uint8_t *fp;
- /* since duk__abandon_array_checked() causes a resize, there should be no gaps in keys */
+ /* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */
DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);
/* avoid multiple computations of flags address; bypasses macros */
@@ -60172,7 +60845,7 @@ DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_ho
DUK_HOBJECT_CLEAR_EXTENSIBLE(obj);
- /* no need to compact since we already did that in duk__abandon_array_checked()
+ /* no need to compact since we already did that in duk__abandon_array_part()
* (regardless of whether an array part existed or not.
*/
@@ -60255,6 +60928,19 @@ DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *
#undef DUK__VALSTACK_PROXY_LOOKUP
#undef DUK__VALSTACK_SPACE
/*
+ * duk_hstring assertion helpers.
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_ASSERTIONS)
+
+DUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) {
+ DUK_ASSERT(h != NULL);
+}
+
+#endif /* DUK_USE_ASSERTIONS */
+/*
* Misc support functions
*/
@@ -60632,7 +61318,7 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
DUK_HOBJECT_INCREF(thr, h_objenv);
DUK_D(DUK_DPRINT("duplicated global env: %!O", h_objenv));
- DUK_ASSERT_HOBJENV_VALID((duk_hobjenv *) h_objenv);
+ DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv);
duk_pop_2(thr); /* Pop global object and global env. */
}
@@ -60818,7 +61504,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_HOBJECT_INCREF(thr, global);
DUK_ASSERT(env->has_this == 0);
- DUK_ASSERT_HOBJENV_VALID(env);
+ DUK_HOBJENV_ASSERT_VALID(env);
} else {
DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);
@@ -60873,6 +61559,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h));
/* DUK_HOBJECT_FLAG_NATFUNC varies */
DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h));
+ DUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h));
DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY);
/* DUK_HOBJECT_FLAG_STRICT varies */
DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) || /* all native functions have NEWENV */
@@ -61356,7 +62043,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)
for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
DUK_DD(DUK_DDPRINT("built-in object %ld after initialization and compacting: %!@iO",
- (long) i, (duk_heaphdr *) duk_require_hobject(thr, i)));
+ (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i)));
}
#endif
@@ -61674,7 +62361,7 @@ DUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {
duk_tval tv_tmp;
duk_hobject *h_tmp;
- tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
+ tv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);
/* The act->prev_caller should only be set if the entry for 'caller'
* exists (as it is only set in that case, and the property is not
@@ -62072,6 +62759,17 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
* Limit check helpers.
*/
+/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */
+DUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) {
+#if defined(DUK_USE_NATIVE_STACK_CHECK)
+ if (DUK_USE_NATIVE_STACK_CHECK() != 0) {
+ DUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);
+ }
+#else
+ DUK_UNREF(thr);
+#endif
+}
+
/* Allow headroom for calls during error augmentation (see GH-191).
* We allow space for 10 additional recursions, with one extra
* for, e.g. a print() call at the deepest level, and an extra
@@ -62079,6 +62777,9 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
*/
#define DUK__AUGMENT_CALL_RELAX_COUNT (10 + 2)
+/* Stack space required by call handling entry. */
+#define DUK__CALL_HANDLING_REQUIRE_STACK 8
+
DUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {
/* When augmenting an error, the effective limit is a bit higher.
* Check for it only if the fast path check fails.
@@ -62093,7 +62794,7 @@ DUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthre
#endif
DUK_D(DUK_DPRINT("call prevented because C recursion limit reached"));
- DUK_ERROR_RANGE(thr, DUK_STR_C_CALLSTACK_LIMIT);
+ DUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);
DUK_WO_NORETURN(return;);
}
@@ -62101,6 +62802,8 @@ DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *
DUK_ASSERT(thr->heap->call_recursion_depth >= 0);
DUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);
+ duk_native_stack_check(thr);
+
/* This check is forcibly inlined because it's very cheap and almost
* always passes. The slow path is forcibly noinline.
*/
@@ -62220,11 +62923,10 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
DUK_ASSERT(i_argbase >= 0);
DUK_ASSERT(num_stack_args >= 0);
- duk_push_hobject(thr, func);
- duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FORMALS);
- formals = duk_get_hobject(thr, -1);
+ formals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func);
if (formals) {
- n_formals = (duk_idx_t) duk_get_length(thr, -1);
+ n_formals = (duk_idx_t) ((duk_harray *) formals)->length;
+ duk_push_hobject(thr, formals);
} else {
/* This shouldn't happen without tampering of internal
* properties: if a function accesses 'arguments', _Formals
@@ -62233,8 +62935,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
*/
DUK_D(DUK_DPRINT("_Formals is undefined when creating arguments, use n_formals == 0"));
n_formals = 0;
+ duk_push_undefined(thr);
}
- duk_remove_m2(thr); /* leave formals on stack for later use */
i_formals = duk_require_top_index(thr);
DUK_ASSERT(n_formals >= 0);
@@ -62249,8 +62951,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
/*
* Create required objects:
* - 'arguments' object: array-like, but not an array
- * - 'map' object: internal object, tied to 'arguments'
- * - 'mappedNames' object: temporary value used during construction
+ * - 'map' object: internal object, tied to 'arguments' (bare)
+ * - 'mappedNames' object: temporary value used during construction (bare)
*/
arg = duk_push_object_helper(thr,
@@ -62273,6 +62975,9 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
i_arg = duk_get_top(thr) - 3;
i_map = i_arg + 1;
i_mappednames = i_arg + 2;
+ DUK_ASSERT(!duk_is_bare_object(thr, -3)); /* arguments */
+ DUK_ASSERT(duk_is_bare_object(thr, -2)); /* map */
+ DUK_ASSERT(duk_is_bare_object(thr, -1)); /* mappedNames */
/* [ ... formals arguments map mappedNames ] */
@@ -62392,7 +63097,7 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("strict function, setting caller/callee to throwers"));
- duk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLER);
+ /* In ES2017 .caller is no longer set at all. */
duk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);
} else {
DUK_DDD(DUK_DDDPRINT("non-strict function, setting callee to actual value"));
@@ -62660,7 +63365,8 @@ DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,
DUK_ASSERT(func != NULL);
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) ||
- DUK_HOBJECT_HAS_NATFUNC(func));
+ DUK_HOBJECT_HAS_NATFUNC(func) ||
+ DUK_HOBJECT_IS_PROXY(func));
}
#endif
}
@@ -62955,6 +63661,7 @@ DUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func,
duk_push_hobject(thr, h_proxy->target);
duk_insert(thr, idx_func + 3);
duk_pack(thr, duk_get_top(thr) - (idx_func + 5));
+ DUK_ASSERT(!duk_is_bare_object(thr, -1));
/* Here:
* idx_func + 0: Proxy object
@@ -63044,7 +63751,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
/* XXX: check .caller writability? */
/* Backup 'caller' property and update its value. */
- tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
+ tv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);
if (tv_caller) {
/* If caller is global/eval code, 'caller' should be set to
* 'null'.
@@ -63231,6 +63938,8 @@ DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *th
tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);
DUK_ASSERT(tv_func != NULL);
+ DUK_DD(DUK_DDPRINT("target func: %!iT", tv_func));
+
if (DUK_TVAL_IS_OBJECT(tv_func)) {
func = DUK_TVAL_GET_OBJECT(tv_func);
@@ -63355,14 +64064,17 @@ DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *th
#if defined(DUK_USE_VERBOSE_ERRORS)
/* GETPROPC delayed error handling: when target is not callable,
- * GETPROPC replaces idx_func+0 with an Error (non-callable) with
- * a hidden Symbol to signify it's to be thrown as is here. The
+ * GETPROPC replaces idx_func+0 with a non-callable wrapper object
+ * with a hidden Symbol to signify it's to be handled here. If
+ * found, unwrap the original Error and throw it as is here. The
* hidden Symbol is only checked as an own property, not inherited
* (which would be dangerous).
*/
if (DUK_TVAL_IS_OBJECT(tv_func)) {
- if (duk_hobject_find_existing_entry_tval_ptr(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_HTHREAD_STRING_INT_TARGET(thr)) != NULL) {
- duk_push_tval(thr, tv_func);
+ duk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET);
+ if (tv_wrap != NULL) {
+ DUK_DD(DUK_DDPRINT("delayed error from GETPROPC: %!T", tv_wrap));
+ duk_push_tval(thr, tv_wrap);
(void) duk_throw(thr);
DUK_WO_NORETURN(return NULL;);
}
@@ -63849,6 +64561,7 @@ DUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_acti
if (DUK_LIKELY(func != NULL)) {
if (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {
+ DUK_STATS_INC(thr->heap, stats_envrec_newenv);
if (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) {
/* Use a new environment but there's no 'arguments' object;
* delayed environment initialization. This is the most
@@ -63885,6 +64598,7 @@ DUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_acti
DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));
+ DUK_STATS_INC(thr->heap, stats_envrec_oldenv);
duk__handle_oldenv_for_call(thr, func, act);
DUK_ASSERT(act->lex_env != NULL);
@@ -63894,6 +64608,7 @@ DUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_acti
/* Lightfuncs are always native functions and have "newenv". */
DUK_ASSERT(act->lex_env == NULL);
DUK_ASSERT(act->var_env == NULL);
+ DUK_STATS_INC(thr->heap, stats_envrec_newenv);
}
}
@@ -63980,7 +64695,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
/* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or
* any other thread (e.g. when heap thread is used to run finalizers).
*/
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_ASSERT(duk_is_valid_index(thr, idx_func));
DUK_ASSERT(idx_func >= 0);
@@ -64063,6 +64778,26 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
duk__call_thread_state_update(thr);
/*
+ * Increase call recursion depth as early as possible so that if we
+ * enter a recursive call for any reason there's a backstop to native
+ * recursion. This can happen e.g. for almost any property read
+ * because it may cause a getter call or a Proxy trap (GC and finalizers
+ * are not an issue because they are not recursive). If we end up
+ * doing an Ecma-to-Ecma call, revert the increase. (See GH-2032.)
+ *
+ * For similar reasons, ensure there is a known value stack spare
+ * even before we actually prepare the value stack for the target
+ * function. If this isn't done, early recursion may consume the
+ * value stack space.
+ *
+ * XXX: Should bump yield preventcount early, for the same reason.
+ */
+
+ duk__call_c_recursion_limit_check(thr);
+ thr->heap->call_recursion_depth++;
+ duk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK);
+
+ /*
* Resolve final target function; handle bound functions and special
* functions like .call() and .apply(). Also figure out the effective
* 'this' binding, which replaces the current value at idx_func + 1.
@@ -64205,6 +64940,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
DUK_REFZERO_CHECK_FAST(thr);
DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ thr->heap->call_recursion_depth--; /* No recursion increase for this case. */
return 1; /* 1=reuse executor */
}
DUK_ASSERT(use_tailcall == 0);
@@ -64214,12 +64950,6 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
act->flags |= DUK_ACT_FLAG_PREVENT_YIELD;
thr->callstack_preventcount++;
- /* XXX: we could just do this on entry regardless of reuse, as long
- * as recursion depth is decreased for e2e case.
- */
- duk__call_c_recursion_limit_check(thr);
- thr->heap->call_recursion_depth++;
-
/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */
/*
@@ -64254,12 +64984,6 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
act->flags |= DUK_ACT_FLAG_PREVENT_YIELD;
thr->callstack_preventcount++;
- /* XXX: we could just do this on entry regardless of reuse, as long
- * as recursion depth is decreased for e2e case.
- */
- duk__call_c_recursion_limit_check(thr);
- thr->heap->call_recursion_depth++;
-
/* For native calls must be NULL so we don't sync back */
DUK_ASSERT(thr->ptr_curr_pc == NULL);
@@ -64453,7 +65177,7 @@ DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,
duk_ret_t rc;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
/*
* Thread state check and book-keeping.
@@ -64511,7 +65235,7 @@ DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,
duk_size_t entry_valstack_bottom_byteoff,
duk_jmpbuf *old_jmpbuf_ptr) {
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
/*
* Error during call. The error value is at heap->lj.value1.
@@ -64603,7 +65327,7 @@ DUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,
duk_hthread *entry_curr_thread,
duk_instr_t **entry_ptr_curr_pc) {
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_CTX_VALID(thr);
+ DUK_CTX_ASSERT_VALID(thr);
DUK_UNREF(idx_retbase);
DUK_UNREF(num_stack_rets);
DUK_UNREF(entry_curr_thread);
@@ -64862,64 +65586,78 @@ DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
/*
* Property-based call (foo.noSuch()) error setup: replace target function
- * on stack top with a specially tagged (hidden Symbol) error which gets
- * thrown in call handling at the proper spot to follow ECMAScript semantics.
+ * on stack top with a hidden Symbol tagged non-callable wrapper object
+ * holding the error. The error gets thrown in call handling at the
+ * proper spot to follow ECMAScript semantics.
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
-DUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_targ, duk_tval *tv_base, duk_tval *tv_key) {
- const char *str1, *str2, *str3;
+DUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) {
+ const char *str_targ, *str_key, *str_base;
duk_idx_t entry_top;
entry_top = duk_get_top(thr);
- /* Must stabilize pointers first. Argument convention is a bit awkward,
- * it comes from the executor call site where some arguments may not be
- * on the value stack (consts).
- */
+ /* [ <nargs> target ] */
+
+ /* Must stabilize pointers first. tv_targ is already on stack top. */
duk_push_tval(thr, tv_base);
duk_push_tval(thr, tv_key);
- duk_push_tval(thr, tv_targ);
DUK_GC_TORTURE(thr->heap);
- /* We only push an error, replacing the call target (at idx_func)
- * with the error to ensure side effects come out correctly:
+ duk_push_bare_object(thr);
+
+ /* [ <nargs> target base key {} ] */
+
+ /* We only push a wrapped error, replacing the call target (at
+ * idx_func) with the error to ensure side effects come out
+ * correctly:
* - Property read
* - Call argument evaluation
- * - Callability check and error thrown.
+ * - Callability check and error thrown
*
- * A hidden Symbol on the error object pushed here is used by
+ * A hidden Symbol on the wrapper object pushed above is used by
* call handling to figure out the error is to be thrown as is.
* It is CRITICAL that the hidden Symbol can never occur on a
* user visible object that may get thrown.
*/
#if defined(DUK_USE_PARANOID_ERRORS)
- str1 = duk_get_type_name(thr, -1);
- str2 = duk_get_type_name(thr, -2);
- str3 = duk_get_type_name(thr, -3);
- duk_push_error_object(thr, DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, "%s not callable (property %s of %s)", str1, str2, str3);
-#else
- str1 = duk_push_string_readable(thr, -1);
- str2 = duk_push_string_readable(thr, -3);
- str3 = duk_push_string_readable(thr, -5);
- duk_push_error_object(thr, DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, "%s not callable (property %s of %s)", str1, str2, str3);
-#endif
-
- duk_push_true(thr);
- duk_put_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET); /* Marker property, reuse _Target. */
-
- /* [ <nregs> propValue <variable> error ] */
+ str_targ = duk_get_type_name(thr, -4);
+ str_key = duk_get_type_name(thr, -2);
+ str_base = duk_get_type_name(thr, -3);
+ duk_push_error_object(thr,
+ DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
+ "%s not callable (property %s of %s)", str_targ, str_key, str_base);
+ duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); /* Marker property, reuse _Target. */
+ /* [ <nargs> target base key { _Target: error } ] */
duk_replace(thr, entry_top - 1);
+#else
+ str_targ = duk_push_string_readable(thr, -4);
+ str_key = duk_push_string_readable(thr, -3);
+ str_base = duk_push_string_readable(thr, -5);
+ duk_push_error_object(thr,
+ DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
+ "%s not callable (property %s of %s)", str_targ, str_key, str_base);
+ /* [ <nargs> target base key {} str_targ str_key str_base error ] */
+ duk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); /* Marker property, reuse _Target. */
+ /* [ <nargs> target base key { _Target: error } str_targ str_key str_base ] */
+ duk_swap(thr, -4, entry_top - 1);
+ /* [ <nargs> { _Target: error } base key target str_targ str_key str_base ] */
+#endif
+
+ /* [ <nregs> { _Target: error } <variable> */
duk_set_top(thr, entry_top);
+ /* [ <nregs> { _Target: error } */
DUK_ASSERT(!duk_is_callable(thr, -1)); /* Critical so that call handling will throw the error. */
}
#endif /* DUK_USE_VERBOSE_ERRORS */
/* automatic undefs */
#undef DUK__AUGMENT_CALL_RELAX_COUNT
+#undef DUK__CALL_HANDLING_REQUIRE_STACK
/*
* ECMAScript compiler.
*
@@ -65290,8 +66028,8 @@ DUK_LOCAL const duk_uint8_t duk__token_lbp[] = {
DUK__MK_LBP(DUK__BP_MULTIPLICATIVE), /* DUK_TOK_DIV */
DUK__MK_LBP(DUK__BP_MULTIPLICATIVE), /* DUK_TOK_MOD */
DUK__MK_LBP(DUK__BP_EXPONENTIATION), /* DUK_TOK_EXP */
- DUK__MK_LBP(DUK__BP_POSTFIX), /* DUK_TOK_INCREMENT */
- DUK__MK_LBP(DUK__BP_POSTFIX), /* DUK_TOK_DECREMENT */
+ DUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_INCREMENT */
+ DUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_DECREMENT */
DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_ALSHIFT */
DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_ARSHIFT */
DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_RSHIFT */
@@ -65464,23 +66202,23 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
DUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));
/* code_idx = entry_top + 0 */
- duk_push_array(thr);
+ duk_push_bare_array(thr);
func->consts_idx = entry_top + 1;
func->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);
DUK_ASSERT(func->h_consts != NULL);
- duk_push_array(thr);
+ duk_push_bare_array(thr);
func->funcs_idx = entry_top + 2;
func->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);
DUK_ASSERT(func->h_funcs != NULL);
DUK_ASSERT(func->fnum_next == 0);
- duk_push_array(thr);
+ duk_push_bare_array(thr);
func->decls_idx = entry_top + 3;
func->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);
DUK_ASSERT(func->h_decls != NULL);
- duk_push_array(thr);
+ duk_push_bare_array(thr);
func->labelnames_idx = entry_top + 4;
func->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);
DUK_ASSERT(func->h_labelnames != NULL);
@@ -65491,7 +66229,7 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(func->h_labelinfos != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));
- duk_push_array(thr);
+ duk_push_bare_array(thr);
func->argnames_idx = entry_top + 6;
func->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);
DUK_ASSERT(func->h_argnames != NULL);
@@ -65702,7 +66440,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
p_const = (duk_tval *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);
for (i = 0; i < consts_count; i++) {
DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* const limits */
- tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);
+ tv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);
DUK_ASSERT(tv != NULL);
DUK_TVAL_SET_TVAL(p_const, tv);
p_const++;
@@ -65716,7 +66454,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
for (i = 0; i < funcs_count; i++) {
duk_hobject *h;
DUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX); /* func limits */
- tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));
+ tv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));
DUK_ASSERT(tv != NULL);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
h = DUK_TVAL_GET_OBJECT(tv);
@@ -65958,7 +66696,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
p = p_start;
while (p < p_end) {
- DUK_DDD(DUK_DDDPRINT("BC %04ld: %!I ; 0x%08lx op=%ld (%!C) a=%ld b=%ld c=%ld",
+ DUK_DDD(DUK_DDDPRINT("BC %04ld: %!I ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld",
(long) (p - p_start),
(duk_instr_t) (*p),
(unsigned long) (*p),
@@ -66508,7 +67246,7 @@ DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, du
goto error_outofregs;
}
ins = DUK_ENC_OP_ABC(op, abc);
- DUK_DDD(DUK_DDDPRINT("duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!C) abc=%ld (%!I)",
+ DUK_DDD(DUK_DDDPRINT("duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)",
(unsigned long) ins, (long) comp_ctx->curr_token.start_line,
(long) duk__get_current_pc(comp_ctx), (long) op, (long) op,
(long) abc, (duk_instr_t) ins));
@@ -73884,7 +74622,7 @@ DUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, du
DUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);
}
-DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {
+DUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) {
duk_activation *act;
duk_catcher *cat;
@@ -73893,9 +74631,17 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_tval *tv_val_unstable, du
act = thr->callstack_curr;
DUK_ASSERT(act != NULL);
+ DUK_DD(DUK_DDPRINT("handle catch, part 1; act=%!A, cat=%!C", act, act->cat));
+
DUK_ASSERT(act->cat != NULL);
DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);
+ /* The part1/part2 split could also be made here at the very top
+ * of catch handling. Value stack would be reconfigured inside
+ * part2's protection. Value stack reconfiguration should be free
+ * of allocs, however.
+ */
+
duk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);
DUK_ASSERT(thr->callstack_top >= 1);
@@ -73917,8 +74663,44 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_tval *tv_val_unstable, du
act->curr_pc = cat->pc_base + 0; /* +0 = catch */
/*
- * If entering a 'catch' block which requires an automatic
- * catch variable binding, create the lexical environment.
+ * If the catch block has an automatic catch variable binding,
+ * we need to create a lexical environment for it which requires
+ * allocations. Move out of "error handling state" before the
+ * allocations to avoid e.g. out-of-memory errors (leading to
+ * GH-2022 or similar).
+ */
+
+ if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {
+ DUK_DDD(DUK_DDDPRINT("catcher has an automatic catch binding, handle in part 2"));
+ *out_delayed_catch_setup = 1;
+ } else {
+ DUK_DDD(DUK_DDDPRINT("catcher has no catch binding"));
+ }
+
+ DUK_CAT_CLEAR_CATCH_ENABLED(cat);
+}
+
+DUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) {
+ duk_activation *act;
+ duk_catcher *cat;
+ duk_hdecenv *new_env;
+
+ DUK_ASSERT(thr != NULL);
+
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ DUK_DD(DUK_DDPRINT("handle catch, part 2; act=%!A, cat=%!C", act, act->cat));
+
+ DUK_ASSERT(act->cat != NULL);
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
+ DUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));
+ DUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);
+
+ /*
+ * Create lexical environment for the catch clause, containing
+ * a binding for the caught value.
*
* The binding is mutable (= writable) but not deletable.
* Step 4 for the catch production in E5 Section 12.14;
@@ -73926,70 +74708,56 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_tval *tv_val_unstable, du
* which implies the binding is not deletable.
*/
- if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {
- duk_hdecenv *new_env;
-
- DUK_DDD(DUK_DDDPRINT("catcher has an automatic catch binding"));
+ if (act->lex_env == NULL) {
+ DUK_ASSERT(act->var_env == NULL);
+ DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
- DUK_ASSERT(thr->callstack_top >= 1);
+ duk_js_init_activation_environment_records_delayed(thr, act);
DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
+ }
+ DUK_ASSERT(act->lex_env != NULL);
+ DUK_ASSERT(act->var_env != NULL);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
- if (act->lex_env == NULL) {
- DUK_ASSERT(act->var_env == NULL);
- DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
-
- duk_js_init_activation_environment_records_delayed(thr, act);
- DUK_ASSERT(act == thr->callstack_curr);
- DUK_ASSERT(act != NULL);
- }
- DUK_ASSERT(act->lex_env != NULL);
- DUK_ASSERT(act->var_env != NULL);
- DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
+ new_env = duk_hdecenv_alloc(thr,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
+ DUK_ASSERT(new_env != NULL);
+ duk_push_hobject(thr, (duk_hobject *) new_env);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
+ DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *) new_env));
- /* XXX: If an out-of-memory happens here, longjmp state asserts
- * will be triggered at present and a try-catch fails to catch.
- * That's not sandboxing fatal (C API protected calls are what
- * matters), and script catch code can immediately throw anyway
- * for almost any operation.
- */
- new_env = duk_hdecenv_alloc(thr,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
- DUK_ASSERT(new_env != NULL);
- duk_push_hobject(thr, (duk_hobject *) new_env);
- DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
- DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *) new_env));
+ /* Note: currently the catch binding is handled without a register
+ * binding because we don't support dynamic register bindings (they
+ * must be fixed for an entire function). So, there is no need to
+ * record regbases etc.
+ */
- /* Note: currently the catch binding is handled without a register
- * binding because we don't support dynamic register bindings (they
- * must be fixed for an entire function). So, there is no need to
- * record regbases etc.
- */
+ /* [ ...env ] */
- /* XXX: duk_xdef_prop() may cause an out-of-memory, see above. */
- DUK_ASSERT(cat->h_varname != NULL);
- duk_push_hstring(thr, cat->h_varname);
- duk_push_tval(thr, thr->valstack + cat->idx_base);
- duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */
+ DUK_ASSERT(cat->h_varname != NULL);
+ duk_push_hstring(thr, cat->h_varname);
+ DUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);
+ duk_push_tval(thr, thr->valstack + cat->idx_base);
+ duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */
- DUK_ASSERT(act == thr->callstack_curr);
- DUK_ASSERT(act != NULL);
- DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);
- act->lex_env = (duk_hobject *) new_env;
- DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env); /* reachable through activation */
- /* Net refcount change to act->lex_env is 0: incref for new_env's
- * prototype, decref for act->lex_env overwrite.
- */
+ /* [ ... env ] */
- DUK_CAT_SET_LEXENV_ACTIVE(cat);
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(act != NULL);
+ DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);
+ act->lex_env = (duk_hobject *) new_env;
+ DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env); /* reachable through activation */
+ /* Net refcount change to act->lex_env is 0: incref for new_env's
+ * prototype, decref for act->lex_env overwrite.
+ */
- duk_pop_unsafe(thr);
+ DUK_CAT_SET_LEXENV_ACTIVE(cat);
- DUK_DDD(DUK_DDDPRINT("new_env finished: %!iO", (duk_heaphdr *) new_env));
- }
+ duk_pop_unsafe(thr);
- DUK_CAT_CLEAR_CATCH_ENABLED(cat);
+ DUK_DDD(DUK_DDDPRINT("new_env finished: %!iO", (duk_heaphdr *) new_env));
}
DUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {
@@ -74082,7 +74850,7 @@ DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tva
}
#endif /* DUK_USE_COROUTINE_SUPPORT */
-DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act) {
+DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) {
duk_small_uint_t retval = DUK__LONGJMP_RESTART;
DUK_ASSERT(thr != NULL);
@@ -74105,11 +74873,12 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
check_longjmp:
- DUK_DD(DUK_DDPRINT("handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld",
+ DUK_DD(DUK_DDPRINT("handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld",
(long) thr->heap->lj.type,
(duk_tval *) &thr->heap->lj.value1,
(duk_tval *) &thr->heap->lj.value2,
- (long) thr->heap->lj.iserror));
+ (long) thr->heap->lj.iserror,
+ (long) duk_get_top(thr)));
switch (thr->heap->lj.type) {
@@ -74375,9 +75144,12 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
- duk__handle_catch(thr,
- &thr->heap->lj.value1,
- DUK_LJ_TYPE_THROW);
+ DUK_DDD(DUK_DDDPRINT("before catch part 1: thr=%p, act=%p, cat=%p",
+ (void *) thr, (void *) act, (void *) act->cat));
+ duk__handle_catch_part1(thr,
+ &thr->heap->lj.value1,
+ DUK_LJ_TYPE_THROW,
+ out_delayed_catch_setup);
DUK_DD(DUK_DDPRINT("-> throw caught by a 'catch' clause, restart execution"));
retval = DUK__LONGJMP_RESTART;
@@ -74459,7 +75231,8 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
DUK_UNREACHABLE();
wipe_and_return:
- /* this is not strictly necessary, but helps debugging */
+ DUK_DD(DUK_DDPRINT("handling longjmp done, wipe-and-return, top=%ld",
+ (long) duk_get_top(thr)));
thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;
thr->heap->lj.iserror = 0;
@@ -75077,7 +75850,7 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
bp_active = heap->dbg_breakpoints_active;
act->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE;
- tv_tmp = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) fun, DUK_HTHREAD_STRING_FILE_NAME(thr));
+ tv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME);
if (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) {
filename = DUK_TVAL_GET_STRING(tv_tmp);
@@ -75358,7 +76131,7 @@ DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_
env->target = target; /* always provideThis=true */
DUK_HOBJECT_INCREF(thr, target);
env->has_this = 1;
- DUK_ASSERT_HOBJENV_VALID(env);
+ DUK_HOBJENV_ASSERT_VALID(env);
DUK_DDD(DUK_DDDPRINT("environment for with binding: %!iO", env));
DUK_ASSERT(act == thr->callstack_curr);
@@ -75845,7 +76618,8 @@ DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx,
DUK_LOCAL void duk__handle_executor_error(duk_heap *heap,
duk_activation *entry_act,
duk_int_t entry_call_recursion_depth,
- duk_jmpbuf *entry_jmpbuf_ptr) {
+ duk_jmpbuf *entry_jmpbuf_ptr,
+ volatile duk_bool_t *out_delayed_catch_setup) {
duk_small_uint_t lj_ret;
/* Longjmp callers are required to sync-and-null thr->ptr_curr_pc
@@ -75865,7 +76639,7 @@ DUK_LOCAL void duk__handle_executor_error(duk_heap *heap,
*/
heap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;
- lj_ret = duk__handle_longjmp(heap->curr_thread, entry_act);
+ lj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup);
/* Error handling complete, remove side effect protections.
*/
@@ -75904,6 +76678,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
duk_jmpbuf *entry_jmpbuf_ptr;
duk_jmpbuf our_jmpbuf;
duk_heap *heap;
+ volatile duk_bool_t delayed_catch_setup = 0;
DUK_ASSERT(exec_thr != NULL);
DUK_ASSERT(exec_thr->heap != NULL);
@@ -75942,6 +76717,17 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
DUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf);
if (DUK_SETJMP(our_jmpbuf.jb) == 0) {
#endif
+ DUK_DDD(DUK_DDDPRINT("after setjmp, delayed catch setup: %ld\n", (long) delayed_catch_setup));
+
+ if (DUK_UNLIKELY(delayed_catch_setup != 0)) {
+ duk_hthread *thr = entry_thread->heap->curr_thread;
+
+ delayed_catch_setup = 0;
+ duk__handle_catch_part2(thr);
+ DUK_ASSERT(delayed_catch_setup == 0);
+ DUK_DDD(DUK_DDDPRINT("top after delayed catch setup: %ld", (long) duk_get_top(entry_thread)));
+ }
+
/* Execute bytecode until returned or longjmp(). */
duk__js_execute_bytecode_inner(entry_thread, entry_act);
@@ -75963,7 +76749,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
duk__handle_executor_error(heap,
entry_act,
entry_call_recursion_depth,
- entry_jmpbuf_ptr);
+ entry_jmpbuf_ptr,
+ &delayed_catch_setup);
}
#if defined(DUK_USE_CPP_EXCEPTIONS)
catch (duk_fatal_exception &exc) {
@@ -75986,7 +76773,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
duk__handle_executor_error(heap,
entry_act,
entry_call_recursion_depth,
- entry_jmpbuf_ptr);
+ entry_jmpbuf_ptr,
+ &delayed_catch_setup);
}
} catch (...) {
DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)"));
@@ -76001,7 +76789,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
duk__handle_executor_error(heap,
entry_act,
entry_call_recursion_depth,
- entry_jmpbuf_ptr);
+ entry_jmpbuf_ptr,
+ &delayed_catch_setup);
}
}
#endif
@@ -77181,7 +77970,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* arguments to deal with potentially changed \
* valstack base pointer! \
*/ \
- duk_call_setup_propcall_error(thr, tv__targ, (barg), (carg)); \
+ duk_call_setup_propcall_error(thr, (barg), (carg)); \
} \
DUK__REPLACE_TOP_A_BREAK(); \
}
@@ -78395,7 +79184,8 @@ DUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {
* ("0x123") and infinities
*
* - Unlike source code literals, ToNumber() coerces empty strings
- * and strings with only whitespace to zero (not NaN).
+ * and strings with only whitespace to zero (not NaN). However,
+ * while '' coerces to 0, '+' and '-' coerce to NaN.
*/
/* E5 Section 9.3.1 */
@@ -79833,6 +80623,7 @@ void duk_js_push_closure(duk_hthread *thr,
duk_hobject *outer_lex_env,
duk_bool_t add_auto_proto) {
duk_hcompfunc *fun_clos;
+ duk_harray *formals;
duk_small_uint_t i;
duk_uint_t len_value;
@@ -79844,6 +80635,8 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_ASSERT(outer_lex_env != NULL);
DUK_UNREF(len_value);
+ DUK_STATS_INC(thr->heap, stats_envrec_pushclosure);
+
fun_clos = duk_push_hcompfunc(thr);
DUK_ASSERT(fun_clos != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
@@ -80039,6 +80832,11 @@ void duk_js_push_closure(duk_hthread *thr,
*
* The properties will be non-writable and non-enumerable, but
* configurable.
+ *
+ * Function templates are bare objects, so inheritance of internal
+ * Symbols is not an issue here even when using ordinary property
+ * reads. The function instance created is not bare, so internal
+ * Symbols must be defined without inheritance checks.
*/
/* [ ... closure template ] */
@@ -80049,7 +80847,7 @@ void duk_js_push_closure(duk_hthread *thr,
for (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {
duk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];
- if (duk_get_prop_stridx_short(thr, -1, stridx)) {
+ if (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) {
/* [ ... closure template val ] */
DUK_DDD(DUK_DDDPRINT("copying property, stridx=%ld -> found", (long) stridx));
duk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);
@@ -80068,18 +80866,14 @@ void duk_js_push_closure(duk_hthread *thr,
/* [ ... closure template ] */
- /* XXX: these lookups should be just own property lookups instead of
- * looking up the inheritance chain.
- */
- if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FORMALS)) {
- /* [ ... closure template formals ] */
- len_value = (duk_uint_t) duk_get_length(thr, -1); /* could access duk_harray directly, not important */
+ formals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp);
+ if (formals) {
+ len_value = (duk_uint_t) formals->length;
DUK_DD(DUK_DDPRINT("closure length from _Formals -> %ld", (long) len_value));
} else {
len_value = fun_temp->nargs;
DUK_DD(DUK_DDPRINT("closure length defaulted from nargs -> %ld", (long) len_value));
}
- duk_pop_unsafe(thr);
duk_push_uint(thr, len_value); /* [ ... closure template len_value ] */
duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
@@ -80205,6 +80999,29 @@ void duk_js_push_closure(duk_hthread *thr,
* The non-delayed initialization is handled by duk_handle_call().
*/
+DUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) {
+ duk_uint_fast32_t i;
+
+ for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {
+ duk_hstring *key;
+
+ key = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);
+ DUK_ASSERT(key != NULL); /* assume keys are compact in _Varmap */
+ DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i)); /* assume plain values */
+
+ /* Predefine as 'undefined' to reserve a property slot.
+ * This makes the unwind process (where register values
+ * are copied to the env object) safe against throwing.
+ *
+ * XXX: This could be made much faster by creating the
+ * property table directly.
+ */
+ duk_push_undefined(thr);
+ DUK_DDD(DUK_DDDPRINT("preallocate env entry for key %!O", key));
+ duk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);
+ }
+}
+
/* shared helper */
DUK_INTERNAL
duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
@@ -80217,6 +81034,8 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(func != NULL);
+ DUK_STATS_INC(thr->heap, stats_envrec_create);
+
f = (duk_hcompfunc *) func;
parent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);
if (!parent) {
@@ -80240,18 +81059,19 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_ASSERT(env->regbase_byteoff == 0);
if (DUK_HOBJECT_IS_COMPFUNC(func)) {
duk_hobject *varmap;
- duk_tval *tv;
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
- if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
- varmap = DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(varmap != NULL);
+ varmap = duk_hobject_get_varmap(thr, func);
+ if (varmap != NULL) {
env->varmap = varmap;
DUK_HOBJECT_INCREF(thr, varmap);
env->thread = thr;
DUK_HTHREAD_INCREF(thr, thr);
env->regbase_byteoff = bottom_byteoff;
+
+ /* Preallocate env property table to avoid potential
+ * for out-of-memory on unwind when the env is closed.
+ */
+ duk__preallocate_env_entries(thr, varmap, (duk_hobject *) env);
} else {
/* If function has no _Varmap, leave the environment closed. */
DUK_ASSERT(env->thread == NULL);
@@ -80282,6 +81102,8 @@ void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
DUK_ASSERT(act->lex_env == NULL);
DUK_ASSERT(act->var_env == NULL);
+ DUK_STATS_INC(thr->heap, stats_envrec_delayedcreate);
+
env = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);
DUK_ASSERT(env != NULL);
/* 'act' is a stable pointer, so still OK. */
@@ -80335,7 +81157,7 @@ DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject
return;
}
DUK_ASSERT(((duk_hdecenv *) env)->thread != NULL);
- DUK_ASSERT_HDECENV_VALID((duk_hdecenv *) env);
+ DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);
DUK_DDD(DUK_DDDPRINT("closing env: %!iO", (duk_heaphdr *) env));
DUK_DDD(DUK_DDDPRINT("varmap: %!O", (duk_heaphdr *) varmap));
@@ -80386,9 +81208,17 @@ DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject
DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);
DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);
- /* If property already exists, overwrites silently.
+ /* Write register value into env as named properties.
+ * If property already exists, overwrites silently.
* Property is writable, but not deletable (not configurable
* in terms of property attributes).
+ *
+ * This property write must not throw because we're unwinding
+ * and unwind code is not allowed to throw at present. The
+ * call itself has no such guarantees, but we've preallocated
+ * entries for each property when the env was created, so no
+ * out-of-memory error should be possible. If this guarantee
+ * is not provided, problems like GH-476 may happen.
*/
duk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));
DUK_DDD(DUK_DDDPRINT("closing identifier %!O -> reg %ld, value %!T",
@@ -80445,7 +81275,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
DUK_ASSERT(out != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env));
- DUK_ASSERT_HDECENV_VALID(env);
+ DUK_HDECENV_ASSERT_VALID(env);
if (env->thread == NULL) {
/* already closed */
@@ -80453,7 +81283,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
}
DUK_ASSERT(env->varmap != NULL);
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, env->varmap, name);
+ tv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name);
if (DUK_UNLIKELY(tv == NULL)) {
return 0;
}
@@ -80503,16 +81333,13 @@ duk_bool_t duk__getid_activation_regs(duk_hthread *thr,
return 0;
}
- /* XXX: move varmap to duk_hcompfunc struct field. */
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_INT_VARMAP(thr));
- if (!tv) {
+ /* XXX: move varmap to duk_hcompfunc struct field? */
+ varmap = duk_hobject_get_varmap(thr, func);
+ if (!varmap) {
return 0;
}
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
- varmap = DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(varmap != NULL);
- tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, varmap, name);
+ tv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name);
if (!tv) {
return 0;
}
@@ -80659,7 +81486,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
* register-bound variables.
*/
- DUK_ASSERT_HDECENV_VALID((duk_hdecenv *) env);
+ DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);
if (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) {
DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference successful: "
"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O "
@@ -80670,7 +81497,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
return 1;
}
- tv = duk_hobject_find_existing_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);
+ tv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);
if (tv) {
out->value = tv;
out->attrs = attrs;
@@ -80705,7 +81532,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
duk_bool_t found;
DUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);
- DUK_ASSERT_HOBJENV_VALID((duk_hobjenv *) env);
+ DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);
target = ((duk_hobjenv *) env)->target;
DUK_ASSERT(target != NULL);
@@ -81288,7 +82115,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
/* must be found: was found earlier, and cannot be inherited */
for (;;) {
DUK_ASSERT(holder != NULL);
- if (duk_hobject_find_existing_entry(thr->heap, holder, name, &e_idx, &h_idx)) {
+ if (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) {
DUK_ASSERT(e_idx >= 0);
break;
}
@@ -81385,10 +82212,10 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
*/
if (DUK_HOBJECT_IS_DECENV(env)) {
- DUK_ASSERT_HDECENV_VALID((duk_hdecenv *) env);
+ DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);
holder = env;
} else {
- DUK_ASSERT_HOBJENV_VALID((duk_hobjenv *) env);
+ DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);
holder = ((duk_hobjenv *) env)->target;
DUK_ASSERT(holder != NULL);
}
@@ -85460,7 +86287,7 @@ DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, du
* Output: [ string ]
*/
-DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
+DUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
duk_double_t x;
duk_small_int_t c;
duk_small_int_t neg;
@@ -85653,6 +86480,11 @@ DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix,
duk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);
}
+DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
+ duk_native_stack_check(thr);
+ duk__numconv_stringify_raw(thr, radix, digits, flags);
+}
+
/*
* Exposed string-to-number API
*
@@ -85663,7 +86495,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix,
* fails due to an internal error, an InternalError is thrown.
*/
-DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {
+DUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {
duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
duk_double_t res;
@@ -86013,10 +86845,17 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
goto parse_fail;
}
} else {
- /* empty ("") is allowed in some formats (e.g. Number(''), as zero */
+ /* Empty ("") is allowed in some formats (e.g. Number(''), as zero,
+ * but it must not have a leading +/- sign (GH-2019). Note that
+ * for Number(), h_str is already trimmed so we can check for zero
+ * length and still get Number(' + ') == NaN.
+ */
if ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: empty string not allowed (as zero)"));
goto parse_fail;
+ } else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {
+ DUK_DDD(DUK_DDDPRINT("parse failed: no digits, but not empty (had a +/- sign)"));
+ goto parse_fail;
}
}
} else {
@@ -86185,6 +87024,11 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
DUK_WO_NORETURN(return;);
}
+DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {
+ duk_native_stack_check(thr);
+ duk__numconv_parse_raw(thr, radix, flags);
+}
+
/* automatic undefs */
#undef DUK__BI_MAX_PARTS
#undef DUK__BI_PRINT
@@ -86721,6 +87565,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
DUK_ASSERT(out_atom_info != NULL);
+ duk_native_stack_check(re_ctx->thr);
if (re_ctx->recursion_depth >= re_ctx->recursion_limit) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);
DUK_WO_NORETURN(return;);
@@ -87635,6 +88480,7 @@ DUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const
*/
DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {
+ duk_native_stack_check(re_ctx->thr);
if (re_ctx->recursion_depth >= re_ctx->recursion_limit) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);
DUK_WO_NORETURN(return NULL;);
@@ -88206,7 +89052,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
h_input = duk_to_hstring(thr, -1);
DUK_ASSERT(h_input != NULL);
- duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE); /* [ ... re_obj input ] -> [ ... re_obj input bc ] */
+ duk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE); /* [ ... re_obj input ] -> [ ... re_obj input bc ] */
h_bytecode = duk_require_hstring(thr, -1); /* no regexp instance should exist without a non-configurable bytecode property */
DUK_ASSERT(h_bytecode != NULL);
@@ -88702,10 +89548,28 @@ DUK_LOCAL duk_uint_t duk__selftest_byte_order(void) {
DUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {
duk_uint_t error_count = 0;
+ volatile duk_uint32_t x32_input, x32_output;
duk_uint32_t x32;
+ volatile duk_uint16_t x16_input, x16_output;
duk_uint16_t x16;
duk_double_union du;
duk_double_t du_diff;
+#if defined(DUK_BSWAP64)
+ volatile duk_uint64_t x64_input, x64_output;
+ duk_uint64_t x64;
+#endif
+
+ /* Cover both compile time and runtime bswap operations, as these
+ * may have different bugs.
+ */
+
+ x16_input = 0xbeefUL;
+ x16 = x16_input;
+ x16 = DUK_BSWAP16(x16);
+ x16_output = x16;
+ if (x16_output != (duk_uint16_t) 0xefbeUL) {
+ DUK__FAILED("DUK_BSWAP16");
+ }
x16 = 0xbeefUL;
x16 = DUK_BSWAP16(x16);
@@ -88713,12 +89577,36 @@ DUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {
DUK__FAILED("DUK_BSWAP16");
}
+ x32_input = 0xdeadbeefUL;
+ x32 = x32_input;
+ x32 = DUK_BSWAP32(x32);
+ x32_output = x32;
+ if (x32_output != (duk_uint32_t) 0xefbeaddeUL) {
+ DUK__FAILED("DUK_BSWAP32");
+ }
+
x32 = 0xdeadbeefUL;
x32 = DUK_BSWAP32(x32);
if (x32 != (duk_uint32_t) 0xefbeaddeUL) {
DUK__FAILED("DUK_BSWAP32");
}
+#if defined(DUK_BSWAP64)
+ x64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff);
+ x64 = x64_input;
+ x64 = DUK_BSWAP64(x64);
+ x64_output = x64;
+ if (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {
+ DUK__FAILED("DUK_BSWAP64");
+ }
+
+ x64 = DUK_U64_CONSTANT(0x8899aabbccddeeff);
+ x64 = DUK_BSWAP64(x64);
+ if (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {
+ DUK__FAILED("DUK_BSWAP64");
+ }
+#endif
+
/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))
* (2.008366013071895,)
*/
@@ -89299,6 +90187,16 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint
#endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */
#endif /* DUK_USE_FASTINT */
+
+/*
+ * Assertion helpers.
+ */
+
+#if defined(DUK_USE_ASSERTIONS)
+DUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) {
+ DUK_ASSERT(tv != NULL);
+}
+#endif
/*
* Unicode support tables automatically generated during build.
*/
@@ -89324,55 +90222,57 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_ids_noa[1063] = {
+const duk_uint8_t duk_unicode_ids_noa[1116] = {
249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,
-2,240,66,244,50,247,185,249,98,241,99,8,241,127,58,240,182,47,31,241,191,
+2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,
21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,
101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,
19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,
47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,
18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,
12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,
-6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,
-98,34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,
-2,85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,
-35,63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,
-227,240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,
-21,5,15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,
-175,40,240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,
-79,27,43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,
-32,47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,
-32,68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,
-87,52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,
-254,12,146,240,184,132,52,95,70,114,47,74,35,111,26,63,78,240,63,11,242,
-127,0,255,224,244,255,240,0,138,143,60,255,240,4,13,223,7,255,227,127,243,
-95,30,63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,
-243,26,34,35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,
-143,31,240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,
-48,32,240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,
-223,7,95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,
-18,245,207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,
-127,10,207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,
-255,223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,
-240,79,20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,
-194,20,3,240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,
-31,50,15,1,50,34,240,191,30,240,212,240,223,21,114,240,207,13,242,107,240,
-107,240,62,240,47,96,243,159,41,242,62,242,63,254,32,79,37,243,223,29,241,
-47,9,240,207,20,241,191,19,64,223,32,240,3,240,112,32,241,95,2,47,9,244,
-102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,64,240,64,212,249,15,37,
-240,67,242,127,32,240,97,32,250,175,31,241,179,241,111,32,240,96,242,223,
-27,244,127,10,255,224,122,243,15,17,15,242,11,241,136,15,7,12,241,131,63,
-40,242,159,249,130,241,95,3,15,35,240,239,98,98,18,241,111,7,15,254,26,223,
-254,40,207,88,245,255,3,251,79,254,155,15,254,50,31,254,236,95,254,19,159,
-255,0,16,173,255,225,43,143,15,246,63,14,240,79,32,240,35,241,31,5,111,3,
-255,226,100,243,92,15,52,207,50,31,16,255,240,0,109,255,5,255,225,229,255,
-240,1,64,31,254,1,31,67,255,224,126,255,231,248,245,182,196,136,159,255,0,
-6,90,244,82,243,114,19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,
-98,255,224,70,63,9,47,9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,
-239,40,251,95,45,243,79,254,59,3,47,11,33,32,48,41,35,32,32,112,80,32,32,
-34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,98,36,47,1,255,240,0,
-3,143,255,0,149,201,241,191,254,242,124,252,227,255,240,0,87,79,0,255,240,
-0,194,63,254,177,63,254,17,0,
+6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,
+2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,
+24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,
+54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,
+166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,
+152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,
+242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,
+136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,
+47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,
+68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,
+52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,
+12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,
+255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,
+63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,
+34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,
+240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,
+240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,
+95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,
+207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,
+207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255,
+223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,240,79,
+20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,3,
+240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,1,
+50,34,240,223,28,240,212,240,223,21,114,240,207,13,242,107,240,107,240,62,
+240,47,96,243,159,41,242,62,242,62,241,79,254,13,15,13,176,159,6,248,207,7,
+223,37,243,223,29,241,47,9,240,207,20,240,240,207,19,64,223,32,240,3,240,
+112,32,241,95,2,47,9,244,102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,
+64,240,64,212,249,15,37,240,67,240,96,241,47,32,240,97,32,250,175,31,241,
+179,241,111,32,240,96,242,223,27,224,243,159,11,253,127,28,246,111,48,241,
+16,249,39,63,23,240,32,32,240,224,191,24,128,240,112,207,30,240,80,241,79,
+41,255,152,47,21,240,48,242,63,14,246,38,33,47,22,240,112,240,181,33,47,16,
+240,0,255,224,59,240,63,254,0,31,254,40,207,88,245,255,3,251,79,254,155,15,
+254,50,31,254,236,95,254,19,159,255,0,16,173,255,225,43,143,15,246,63,14,
+240,79,32,240,35,241,31,5,111,3,255,225,164,243,15,114,243,182,15,52,207,
+50,18,15,14,255,240,0,110,169,255,225,229,255,240,1,64,31,254,1,31,35,47,3,
+57,255,224,126,255,231,248,245,182,196,136,159,255,0,6,90,244,82,243,114,
+19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,98,255,224,70,63,9,47,
+9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,232,40,241,219,111,2,
+15,254,6,95,28,255,228,8,251,95,45,243,72,15,254,58,131,47,11,33,32,48,41,
+35,32,32,112,80,32,32,34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,
+98,36,47,1,255,240,0,3,143,255,0,149,201,241,191,254,242,124,252,227,255,
+240,0,87,79,0,255,240,0,194,63,254,177,63,254,17,0,
};
#else
/* IdentifierStart production with ASCII and non-BMP excluded */
@@ -89381,35 +90281,35 @@ const duk_uint8_t duk_unicode_ids_noa[1063] = {
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_ids_noabmp[626] = {
+const duk_uint8_t duk_unicode_ids_noabmp[625] = {
249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,
-2,240,66,244,50,247,185,249,98,241,99,8,241,127,58,240,182,47,31,241,191,
+2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,
21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,
101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,
19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,
47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,
18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,
12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,
-6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,
-98,34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,
-2,85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,
-35,63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,
-227,240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,
-21,5,15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,
-175,40,240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,
-79,27,43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,
-32,47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,
-32,68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,
-87,52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,
-254,12,146,240,184,132,52,95,70,114,47,74,35,111,26,63,78,240,63,11,242,
-127,0,255,224,244,255,240,0,138,143,60,255,240,4,13,223,7,255,227,127,243,
-95,30,63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,
-243,26,34,35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,
-143,31,240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,
-48,32,240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,
-223,7,95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,
-18,245,207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,
-127,10,207,73,69,53,53,50,0,
+6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,
+2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,
+24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,
+54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,
+166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,
+152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,
+242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,
+136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,
+47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,
+68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,
+52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,
+12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,
+255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,
+63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,
+34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,
+240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,
+240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,
+95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,
+207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,
+207,73,69,53,53,50,0,
};
#endif
@@ -89444,33 +90344,35 @@ const duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = {
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_idp_m_ids_noa[549] = {
+const duk_uint8_t duk_unicode_idp_m_ids_noa[576] = {
255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,
-245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,241,67,40,34,
-36,241,210,246,173,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
-160,177,57,240,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,240,
-97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
-240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,35,
-242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,
-41,244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
+245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,
+34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
+160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,
+240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,
+9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,
+35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,
+215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,
241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,
242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,
-57,241,237,242,47,4,153,121,246,130,47,5,80,82,50,251,143,42,36,255,225,0,
+57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,
31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,
31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,
-242,79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,
+242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,
29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64,
-248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,228,13,47,
-39,239,17,159,1,63,31,175,39,151,47,22,210,159,37,13,47,34,218,36,159,68,
-183,15,146,182,151,63,42,2,99,19,42,11,19,100,79,178,240,42,159,72,240,77,
-159,199,99,143,13,31,68,240,31,1,159,67,201,159,69,229,159,254,9,169,255,
-224,11,159,26,98,57,10,175,32,240,15,254,8,151,39,240,41,242,175,6,45,246,
-197,64,33,38,32,153,255,240,3,191,169,247,132,242,214,240,185,255,226,235,
-241,239,2,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,134,47,254,71,
-223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,47,1,54,33,36,
-255,231,153,111,95,102,159,255,12,6,154,254,0,
+248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,225,49,57,
+159,254,16,10,250,18,242,126,241,25,240,19,241,250,242,121,114,241,109,41,
+97,241,224,210,242,45,147,73,244,75,112,249,43,105,115,242,145,38,49,50,
+160,177,54,68,251,47,2,169,80,244,63,4,217,252,118,56,240,209,244,79,1,240,
+25,244,60,153,244,94,89,254,78,249,121,253,150,54,64,240,233,241,166,35,
+144,170,242,15,0,255,224,137,114,127,2,159,42,240,98,223,108,84,2,18,98,9,
+159,34,66,18,73,159,254,3,211,255,240,3,165,217,247,132,242,214,240,185,
+255,226,233,2,242,120,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,
+134,47,254,71,223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,
+47,1,54,33,36,255,118,169,255,224,150,223,254,76,166,245,246,105,255,240,
+192,105,175,224,0,
};
#else
/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */
@@ -89481,20 +90383,20 @@ const duk_uint8_t duk_unicode_idp_m_ids_noa[549] = {
const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {
255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,
-245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,241,67,40,34,
-36,241,210,246,173,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
-160,177,57,240,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,240,
-97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
-240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,35,
-242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,
-41,244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
+245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,
+34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
+160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,
+240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,
+9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,
+35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,
+215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,
241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,
242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,
-57,241,237,242,47,4,153,121,246,130,47,5,80,82,50,251,143,42,36,255,225,0,
+57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,
31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,
31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,
-242,79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,
+242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,
29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0,
};
@@ -89511,102 +90413,106 @@ const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {
* Automatically generated by extract_caseconv.py, do not edit!
*/
-const duk_uint8_t duk_unicode_caseconv_uc[1386] = {
-144,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162,
+const duk_uint8_t duk_unicode_caseconv_uc[1411] = {
+152,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162,
128,108,65,1,189,129,254,131,3,173,3,136,6,7,98,7,34,68,15,12,14,140,72,30,
-104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,9,252,9,248,6,28,131,4,
-33,4,62,0,62,16,32,124,64,124,96,48,249,0,249,64,129,243,1,243,129,3,232,3,
-233,1,135,216,7,218,4,15,184,15,221,2,31,114,31,200,8,62,236,63,180,8,125,
-224,127,224,16,251,208,255,80,33,247,193,255,160,67,246,3,247,0,135,244,7,
-246,1,15,240,15,244,2,33,112,33,96,32,73,160,73,108,104,176,192,176,1,121,
-104,0,133,2,106,183,1,58,10,31,232,63,228,38,162,1,1,1,0,48,2,102,2,100,12,
-4,232,4,228,64,10,88,10,81,112,23,160,23,144,96,48,96,48,64,128,104,64,104,
-1,128,218,0,217,130,1,206,1,205,16,3,190,3,188,36,7,228,7,224,160,17,24,17,
-16,144,36,112,36,96,160,110,32,110,0,128,246,64,246,6,2,48,130,48,17,4,139,
-4,138,54,9,132,9,130,28,19,68,19,65,128,240,8,240,4,177,234,17,234,6,3,234,
-35,235,33,11,26,11,25,193,150,64,150,64,50,44,236,44,235,5,76,131,76,128,
-94,154,6,154,0,117,57,29,57,16,122,115,58,115,35,244,239,84,239,32,169,223,
-233,223,130,211,200,211,200,2,167,151,167,150,21,79,107,79,104,8,112,26,
-208,26,192,64,56,160,56,128,192,113,128,113,1,128,249,0,248,130,2,128,1,
-166,4,7,240,7,238,8,177,204,177,200,16,96,49,0,48,224,128,110,64,110,1,1,
-51,83,213,2,0,48,35,192,35,176,64,77,32,50,192,139,73,196,49,193,127,48,2,
-212,14,112,3,252,5,224,4,196,1,36,5,252,1,76,6,0,9,12,6,72,6,68,6,84,7,216,
-6,100,6,96,6,104,8,244,6,120,8,128,6,160,6,156,6,252,7,220,7,116,6,56,7,
-204,7,196,9,64,177,188,9,68,177,180,9,72,177,192,9,76,6,4,9,80,6,24,9,100,
-6,60,9,108,6,64,9,114,158,172,9,128,6,76,9,134,158,176,9,140,6,80,9,150,
-158,52,9,160,6,92,9,172,177,136,9,178,158,180,9,196,177,184,9,200,6,116,9,
-212,6,124,9,244,177,144,10,30,158,196,10,32,6,184,10,36,9,16,10,48,9,20,10,
-72,6,220,10,118,158,200,10,122,158,192,13,20,14,100,13,220,13,216,14,176,
-14,24,15,8,14,140,15,48,14,48,15,64,14,72,15,68,14,96,15,84,14,152,15,88,
-14,128,15,92,15,60,15,192,14,104,15,196,14,132,15,200,15,228,15,204,13,252,
-15,212,14,84,19,60,19,0,114,0,16,72,114,4,16,80,114,8,16,120,114,20,16,136,
-114,24,16,168,114,28,17,136,114,34,153,40,117,230,157,244,117,244,177,140,
-122,108,121,128,126,248,14,100,127,148,127,176,133,56,132,200,134,16,134,
-12,177,132,177,128,177,148,8,232,177,152,8,248,179,204,179,202,158,50,158,
-46,173,78,158,207,48,6,252,0,166,0,166,2,147,1,94,0,39,0,248,64,9,64,97,
-128,114,24,28,200,24,64,24,8,29,134,7,74,6,16,6,2,11,15,2,154,130,169,15,
-75,64,9,0,102,35,210,240,2,160,24,64,244,196,0,174,6,20,61,51,0,44,129,133,
-15,77,64,8,32,87,195,234,16,29,40,24,152,250,150,7,74,6,38,6,0,62,169,129,
-210,129,137,129,128,143,171,96,116,160,98,96,104,67,240,16,248,64,28,200,
-252,12,62,18,7,50,63,5,15,133,1,204,143,193,195,225,96,115,35,240,144,248,
-96,28,200,252,44,62,26,7,50,63,13,15,135,1,204,143,195,195,225,224,115,35,
-241,16,248,64,28,200,252,76,62,18,7,50,63,21,15,133,1,204,143,197,195,225,
-96,115,35,241,144,248,96,28,200,252,108,62,26,7,50,63,29,15,135,1,204,143,
-199,195,225,224,115,35,242,16,249,64,28,200,252,140,62,82,7,50,63,37,15,
-149,1,204,143,201,195,229,96,115,35,242,144,249,96,28,200,252,172,62,90,7,
-50,63,45,15,151,1,204,143,203,195,229,224,115,35,243,16,249,64,28,200,252,
-204,62,82,7,50,63,53,15,149,1,204,143,205,195,229,96,115,35,243,144,249,96,
-28,200,252,236,62,90,7,50,63,61,15,151,1,204,143,207,195,229,224,115,35,
-244,16,251,64,28,200,253,12,62,210,7,50,63,69,15,181,1,204,143,209,195,237,
-96,115,35,244,144,251,96,28,200,253,44,62,218,7,50,63,77,15,183,1,204,143,
-211,195,237,224,115,35,245,16,251,64,28,200,253,76,62,210,7,50,63,85,15,
-181,1,204,143,213,195,237,96,115,35,245,144,251,96,28,200,253,108,62,218,7,
-50,63,93,15,183,1,204,143,215,195,237,224,115,35,246,80,253,208,28,200,253,
-156,7,34,7,50,63,105,1,195,1,204,143,219,64,114,32,104,67,246,248,28,136,
-26,16,28,200,253,228,7,34,7,50,63,133,15,229,1,204,143,225,192,114,224,115,
-35,248,144,28,72,28,200,254,52,7,46,6,132,63,143,129,203,129,161,1,204,143,
-230,64,114,224,115,35,250,88,28,200,24,64,24,0,254,158,7,50,6,16,6,2,63,
-173,1,204,129,161,15,235,224,115,32,97,0,104,67,252,88,29,40,24,64,24,0,
-255,30,7,74,6,16,6,2,63,201,1,208,129,137,143,243,64,116,160,104,67,252,
-248,29,40,24,64,26,16,255,148,63,244,7,50,63,231,1,212,129,204,143,250,64,
-113,224,115,35,254,208,29,72,26,16,255,190,7,82,6,132,7,50,63,249,1,212,
-129,204,253,128,64,8,192,8,223,96,48,2,48,2,79,216,20,0,140,0,153,246,7,
-128,35,0,35,0,36,253,130,96,8,192,8,192,9,159,96,176,2,152,2,167,216,52,0,
-166,0,169,246,39,2,162,2,163,125,138,64,168,128,166,191,98,176,42,32,41,
-223,216,180,10,156,10,141,246,47,2,162,2,158,128,
+104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,8,104,14,72,43,16,253,
+28,189,6,39,240,39,224,24,114,12,16,132,16,248,0,248,64,129,241,1,241,128,
+195,228,3,229,2,7,204,7,206,4,15,160,15,164,6,31,96,31,104,16,62,224,63,
+116,8,125,200,127,32,32,251,176,254,208,33,247,129,255,128,67,239,67,253,
+64,135,223,7,254,129,15,216,15,220,2,31,208,31,216,4,63,192,63,208,8,133,
+192,133,128,129,38,129,37,177,162,195,2,192,5,229,160,2,20,9,170,220,4,232,
+40,127,160,255,144,154,136,4,4,4,0,192,9,152,9,144,48,19,160,19,145,0,41,
+96,41,69,192,94,128,94,65,128,193,128,193,2,1,161,1,160,6,3,104,3,102,8,7,
+56,7,52,64,14,248,14,240,144,31,144,31,130,128,68,96,68,66,64,145,192,145,
+130,129,184,129,184,2,3,217,3,216,24,8,194,8,192,68,18,44,18,40,216,38,16,
+38,8,112,77,16,77,6,3,192,35,192,18,199,168,71,168,24,15,168,143,172,132,
+44,104,44,103,6,89,2,89,0,200,179,176,179,172,21,50,13,50,1,122,104,26,104,
+1,212,228,116,228,65,233,204,233,204,143,211,189,83,188,130,167,127,167,
+126,11,79,35,79,32,10,158,94,158,88,85,61,173,61,160,97,192,107,64,107,1,0,
+226,128,226,3,1,198,1,196,6,3,228,3,226,8,10,0,6,152,16,31,192,31,184,34,
+199,50,199,32,65,128,196,0,195,130,1,185,1,184,4,4,205,79,84,8,0,192,143,0,
+142,193,1,52,128,203,2,45,39,16,199,5,253,0,11,80,57,192,15,240,23,128,19,
+16,4,144,23,240,5,48,24,0,36,48,25,32,25,16,25,80,31,96,25,144,25,128,25,
+160,35,208,25,224,34,0,26,128,26,112,27,240,31,112,29,208,24,224,31,48,31,
+16,37,2,198,240,37,18,198,208,37,34,199,0,37,48,24,16,37,64,24,96,37,144,
+24,240,37,176,25,0,37,202,122,176,38,0,25,48,38,26,122,192,38,48,25,64,38,
+90,120,208,38,128,25,112,38,178,198,32,38,202,122,208,39,18,198,224,39,32,
+25,208,39,80,25,240,39,210,198,64,40,42,124,80,40,122,123,16,40,128,26,224,
+40,144,36,64,40,192,36,80,41,32,27,112,41,218,123,32,41,234,123,0,52,80,57,
+144,55,112,55,96,58,192,56,96,60,32,58,48,60,192,56,192,61,0,57,32,61,16,
+57,128,61,80,58,96,61,96,58,0,61,112,60,240,63,0,57,160,63,16,58,16,63,32,
+63,144,63,48,55,240,63,80,57,80,76,240,76,1,200,0,65,33,200,16,65,65,200,
+32,65,225,200,80,66,33,200,96,66,161,200,112,70,33,200,138,100,161,215,154,
+119,209,215,210,198,49,216,234,124,97,233,177,230,1,251,224,57,145,254,81,
+254,194,20,226,19,34,24,66,24,50,198,18,198,2,198,80,35,162,198,96,35,226,
+207,50,207,42,120,202,120,186,121,74,124,74,124,58,124,42,181,58,123,60,
+192,27,240,2,152,2,152,10,76,5,120,0,156,3,225,0,37,1,134,1,200,96,115,32,
+97,0,96,32,118,24,29,40,24,64,24,8,44,60,10,106,10,164,61,45,0,36,1,152,
+143,75,192,10,128,97,3,211,16,2,184,24,80,244,204,0,178,6,20,61,53,0,32,
+129,95,15,168,64,116,160,98,99,234,88,29,40,24,152,24,0,250,166,7,74,6,38,
+6,2,62,173,129,210,129,137,129,161,15,192,67,225,0,115,35,240,48,248,72,28,
+200,252,20,62,20,7,50,63,7,15,133,129,204,143,194,67,225,128,115,35,240,
+176,248,104,28,200,252,52,62,28,7,50,63,15,15,135,129,204,143,196,67,225,0,
+115,35,241,48,248,72,28,200,252,84,62,20,7,50,63,23,15,133,129,204,143,198,
+67,225,128,115,35,241,176,248,104,28,200,252,116,62,28,7,50,63,31,15,135,
+129,204,143,200,67,229,0,115,35,242,48,249,72,28,200,252,148,62,84,7,50,63,
+39,15,149,129,204,143,202,67,229,128,115,35,242,176,249,104,28,200,252,180,
+62,92,7,50,63,47,15,151,129,204,143,204,67,229,0,115,35,243,48,249,72,28,
+200,252,212,62,84,7,50,63,55,15,149,129,204,143,206,67,229,128,115,35,243,
+176,249,104,28,200,252,244,62,92,7,50,63,63,15,151,129,204,143,208,67,237,
+0,115,35,244,48,251,72,28,200,253,20,62,212,7,50,63,71,15,181,129,204,143,
+210,67,237,128,115,35,244,176,251,104,28,200,253,52,62,220,7,50,63,79,15,
+183,129,204,143,212,67,237,0,115,35,245,48,251,72,28,200,253,84,62,212,7,
+50,63,87,15,181,129,204,143,214,67,237,128,115,35,245,176,251,104,28,200,
+253,116,62,220,7,50,63,95,15,183,129,204,143,217,67,247,64,115,35,246,112,
+28,136,28,200,253,164,7,12,7,50,63,109,1,200,129,161,15,219,224,114,32,104,
+64,115,35,247,144,28,136,28,200,254,20,63,148,7,50,63,135,1,203,129,204,
+143,226,64,113,32,115,35,248,208,28,184,26,16,254,62,7,46,6,132,7,50,63,
+153,1,203,129,204,143,233,96,115,32,97,0,96,3,250,120,28,200,24,64,24,8,
+254,180,7,50,6,132,63,175,129,204,129,132,1,161,15,241,96,116,160,97,0,96,
+3,252,120,29,40,24,64,24,8,255,36,7,66,6,38,63,205,1,210,129,161,15,243,
+224,116,160,97,0,104,67,254,80,255,208,28,200,255,156,7,82,7,50,63,233,1,
+199,129,204,143,251,64,117,32,104,67,254,248,29,72,26,16,28,200,255,228,7,
+82,7,51,246,1,0,35,0,35,125,128,192,8,192,9,63,96,80,2,48,2,103,216,30,0,
+140,0,140,0,147,246,9,128,35,0,35,0,38,125,130,192,10,96,10,159,96,208,2,
+152,2,167,216,156,10,136,10,141,246,41,2,162,2,154,253,138,192,168,128,167,
+127,98,208,42,112,42,55,216,188,10,136,10,122,
};
-const duk_uint8_t duk_unicode_caseconv_lc[680] = {
-152,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0,
+const duk_uint8_t duk_unicode_caseconv_lc[706] = {
+160,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0,
235,65,129,199,1,230,130,3,145,3,177,34,7,70,7,134,36,15,244,13,236,24,32,
0,34,129,0,65,0,67,4,0,166,32,172,41,132,40,11,64,19,9,208,85,184,80,19,
-240,19,248,12,62,16,62,0,32,124,96,124,64,48,249,64,249,0,129,243,129,243,
-1,3,233,3,232,1,135,218,7,216,4,15,196,15,192,8,31,152,31,144,16,63,80,63,
-64,32,126,224,126,192,16,253,208,251,128,33,252,129,247,32,131,251,3,250,0,
-135,246,135,221,129,15,244,15,240,2,31,234,31,122,4,63,240,62,240,8,127,
-232,125,240,17,11,1,11,129,2,75,98,77,3,69,128,5,134,11,203,31,128,143,193,
-127,144,255,160,154,140,4,0,4,4,192,9,144,9,152,48,19,144,19,161,0,41,64,
-41,101,192,94,64,94,129,128,193,0,193,130,1,160,1,161,6,3,102,3,104,8,7,44,
-7,48,72,14,240,14,248,144,31,32,31,48,64,63,0,63,37,0,136,128,136,196,129,
-35,1,35,133,3,112,3,113,4,7,176,7,178,48,17,128,17,132,136,36,80,36,89,176,
-76,16,76,32,224,154,0,154,44,7,128,7,128,101,143,80,15,80,176,31,89,31,81,
-8,88,206,88,208,12,178,0,178,5,145,103,89,103,96,42,100,10,100,18,244,208,
-20,208,35,169,200,169,200,195,211,153,83,153,159,167,121,167,122,5,78,253,
-78,254,22,158,66,158,68,21,60,181,60,184,170,123,74,123,80,67,0,211,1,64,2,
-1,172,1,173,4,3,136,3,140,12,7,20,7,24,16,31,184,31,192,34,199,34,199,48,
-65,128,195,128,196,2,1,184,1,185,5,79,84,4,204,8,0,192,101,128,154,65,1,29,
-129,30,2,16,199,45,39,5,251,240,23,128,15,240,24,16,37,48,24,96,37,64,24,
-224,29,208,24,240,37,144,25,0,37,176,25,16,25,32,25,48,38,0,25,64,38,48,25,
-112,38,128,25,128,25,144,25,208,39,32,25,240,39,80,26,112,26,128,26,224,40,
-128,27,112,41,32,31,16,31,48,31,96,25,80,31,112,27,240,34,0,25,224,35,162,
-198,80,35,208,25,160,35,226,198,96,36,48,24,0,36,64,40,144,36,80,40,192,55,
-96,55,112,55,240,63,48,56,96,58,192,56,192,60,192,60,240,61,112,63,64,59,
-128,63,144,63,32,76,0,76,241,233,224,13,241,251,193,251,49,252,193,252,49,
-254,193,254,81,255,193,255,50,18,96,60,146,18,160,6,178,18,176,14,82,19,34,
-20,226,24,50,24,66,198,2,198,18,198,32,38,178,198,49,215,210,198,64,39,210,
-198,208,37,18,198,224,39,18,198,240,37,2,199,0,37,34,207,34,207,58,119,209,
-215,154,120,186,120,202,120,208,38,90,122,176,37,202,122,192,38,26,122,208,
-38,202,123,0,41,234,123,16,40,122,123,32,41,218,123,58,181,48,32,38,16,3,
-72,24,56,
+240,19,248,12,57,32,33,160,172,114,244,67,244,24,248,64,248,0,129,241,129,
+241,0,195,229,3,228,2,7,206,7,204,4,15,164,15,160,6,31,104,31,96,16,63,16,
+63,0,32,126,96,126,64,64,253,64,253,0,129,251,129,251,0,67,247,67,238,0,
+135,242,7,220,130,15,236,15,232,2,31,218,31,118,4,63,208,63,192,8,127,168,
+125,232,16,255,192,251,192,33,255,161,247,192,68,44,4,46,4,9,45,137,52,13,
+22,0,22,24,47,44,126,2,63,5,254,67,254,130,106,48,16,0,16,19,0,38,64,38,96,
+192,78,64,78,132,0,165,0,165,151,1,121,1,122,6,3,4,3,6,8,6,128,6,132,24,13,
+152,13,160,32,28,176,28,193,32,59,192,59,226,64,124,128,124,193,0,252,0,
+252,148,2,34,2,35,18,4,140,4,142,20,13,192,13,196,16,30,192,30,200,192,70,
+0,70,18,32,145,64,145,102,193,48,65,48,131,130,104,2,104,176,30,0,30,1,150,
+61,64,61,66,192,125,100,125,68,33,99,57,99,64,50,200,2,200,22,69,157,101,
+157,128,169,144,41,144,75,211,64,83,64,142,167,34,167,35,15,78,101,78,102,
+126,157,230,157,232,21,59,245,59,248,90,121,10,121,16,84,242,212,242,226,
+169,237,41,237,67,12,3,76,5,0,8,6,176,6,180,16,14,32,14,48,48,28,80,28,96,
+64,126,224,127,0,139,28,139,28,193,6,3,14,3,16,8,6,224,6,228,21,61,80,19,
+48,32,3,1,150,2,105,4,4,118,4,120,8,67,28,180,156,23,240,192,94,0,63,192,
+96,64,148,192,97,128,149,0,99,128,119,64,99,192,150,64,100,0,150,192,100,
+64,100,128,100,192,152,0,101,0,152,192,101,192,154,0,102,0,102,64,103,64,
+156,128,103,192,157,64,105,192,106,0,107,128,162,0,109,192,164,128,124,64,
+124,192,125,128,101,64,125,192,111,192,136,0,103,128,142,139,25,64,143,64,
+102,128,143,139,25,128,144,192,96,0,145,0,162,64,145,64,163,0,221,128,221,
+192,223,192,252,192,225,128,235,0,227,0,243,0,243,192,245,192,253,0,238,0,
+254,64,252,129,48,1,51,199,167,128,55,199,239,7,236,199,243,7,240,199,251,
+7,249,71,255,7,252,200,73,128,242,72,74,128,26,200,74,192,57,72,76,136,83,
+136,96,200,97,11,24,11,24,75,24,128,154,203,24,199,95,75,25,0,159,75,27,64,
+148,75,27,128,156,75,27,192,148,11,28,0,148,139,60,139,60,233,223,71,94,
+105,226,233,227,41,227,64,153,105,234,192,151,41,235,0,152,105,235,64,155,
+41,236,0,167,169,236,64,161,233,236,128,167,105,236,234,212,233,240,169,
+240,233,241,41,229,41,241,64,160,169,241,135,99,128,128,152,64,13,32,96,
+224,
};
#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)
@@ -89649,5797 +90555,5798 @@ const duk_uint16_t duk_unicode_re_canon_lookup[65536] = {
11373,11376,385,390,597,393,394,600,399,602,400,42923L,605,606,607,403,
42924L,610,404,612,42893L,42922L,615,407,406,42926L,11362,42925L,621,622,
412,624,11374,413,627,628,415,630,631,632,633,634,635,636,11364,638,639,
-422,641,642,425,644,645,646,42929L,430,580,433,434,581,653,654,655,656,657,
-439,659,660,661,662,663,664,665,666,667,668,42930L,42928L,671,672,673,674,
-675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,
-693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,
-711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,
-729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,
-747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,
-765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,
-783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,
-801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,
-819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,
-921,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,
-855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,
-873,874,875,876,877,878,879,880,880,882,882,884,885,886,886,888,889,890,
-1021,1022,1023,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,
-909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,
-927,928,929,930,931,932,933,934,935,936,937,938,939,902,904,905,906,944,
-913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,
-931,932,933,934,935,936,937,938,939,908,910,911,975,914,920,978,979,980,
-934,928,975,984,984,986,986,988,988,990,990,992,992,994,994,996,996,998,
-998,1000,1000,1002,1002,1004,1004,1006,1006,922,929,1017,895,1012,917,1014,
-1015,1015,1017,1018,1018,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,
-1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,
-1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,
-1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1040,1041,1042,
-1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,
-1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1024,
-1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,
-1120,1120,1122,1122,1124,1124,1126,1126,1128,1128,1130,1130,1132,1132,1134,
-1134,1136,1136,1138,1138,1140,1140,1142,1142,1144,1144,1146,1146,1148,1148,
-1150,1150,1152,1152,1154,1155,1156,1157,1158,1159,1160,1161,1162,1162,1164,
-1164,1166,1166,1168,1168,1170,1170,1172,1172,1174,1174,1176,1176,1178,1178,
-1180,1180,1182,1182,1184,1184,1186,1186,1188,1188,1190,1190,1192,1192,1194,
-1194,1196,1196,1198,1198,1200,1200,1202,1202,1204,1204,1206,1206,1208,1208,
-1210,1210,1212,1212,1214,1214,1216,1217,1217,1219,1219,1221,1221,1223,1223,
-1225,1225,1227,1227,1229,1229,1216,1232,1232,1234,1234,1236,1236,1238,1238,
-1240,1240,1242,1242,1244,1244,1246,1246,1248,1248,1250,1250,1252,1252,1254,
-1254,1256,1256,1258,1258,1260,1260,1262,1262,1264,1264,1266,1266,1268,1268,
-1270,1270,1272,1272,1274,1274,1276,1276,1278,1278,1280,1280,1282,1282,1284,
-1284,1286,1286,1288,1288,1290,1290,1292,1292,1294,1294,1296,1296,1298,1298,
-1300,1300,1302,1302,1304,1304,1306,1306,1308,1308,1310,1310,1312,1312,1314,
-1314,1316,1316,1318,1318,1320,1320,1322,1322,1324,1324,1326,1326,1328,1329,
-1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,
-1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,
-1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,
-1375,1376,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,
-1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,
-1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1415,1416,1417,1418,1419,
-1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,
-1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,
-1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,
-1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,
-1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,
-1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,
-1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,
-1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,
-1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,
-1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,
-1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,
-1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,
-1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,
-1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,
-1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,
-1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,
-1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,
-1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,
-1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,
-1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,
-1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,
-1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,
-1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,
-1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,
-1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,
-1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,
-1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,
-1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,
-1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,
-1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,
-1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,
-1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,
-1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,
-1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,
-1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,
-1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,
-1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,
-1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,
-1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,
-2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,
-2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,
-2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,
-2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,
-2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,
-2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,
-2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,
-2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,
-2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,
-2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,
-2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,
-2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,
-2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,
-2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,
-2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,
-2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,
-2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,
-2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,2274,
-2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,
-2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,
-2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,
-2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,
-2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,
-2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,2364,
-2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,
-2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,2394,
-2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,
-2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,
-2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,2439,
-2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,2454,
-2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,
-2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,
-2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,2499,
-2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,2514,
-2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,2529,
-2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2544,
-2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,
-2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,
-2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,
-2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,2604,
-2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,2619,
-2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,2634,
-2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,
-2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,2664,
-2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,2679,
-2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,2694,
-2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,2709,
-2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,
-2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,
-2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,
-2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,
-2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,2784,
-2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,
-2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,2814,
-2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,2829,
-2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,
-2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,2859,
-2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,2874,
-2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,2889,
-2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,
-2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,
-2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,2934,
-2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,2949,
-2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,2964,
-2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,
-2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,2994,
-2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,
-3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,
-3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,
-3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,
-3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,
-3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,
-3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,
-3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,3114,
-3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,
-3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,
-3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,3159,
-3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,
-3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189,
-3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203,3204,
-3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,3219,
-3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,
-3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,
-3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264,
-3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,3279,
-3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,
-3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,
-3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,
-3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,
-3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,
-3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,
-3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,
-3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,
-3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,3414,
-3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428,3429,
-3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443,3444,
-3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,
-3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,
-3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,3489,
-3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,3504,
-3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,3519,
-3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533,3534,
-3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548,3549,
-3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,3564,
-3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,3579,
-3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,
-3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,
-3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,
-3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,
-3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,
-3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,
-3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,
-3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,3699,
-3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,3714,
-3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728,3729,
-3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,3744,
-3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,3759,
-3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,3774,
-3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788,3789,
-3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,3804,
-3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818,3819,
-3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,3834,
-3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,3849,
-3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,3864,
-3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,3879,
-3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,
-3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,
-3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,
-3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,
-3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,
-3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,
-3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,3984,
-3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,3999,
-4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,
-4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,
-4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,
-4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,4059,
-4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,
-4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,4089,
-4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,4104,
-4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,4119,
-4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,
-4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,
-4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,4164,
-4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178,4179,
-4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,4194,
-4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,4209,
-4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,
-4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,4239,
-4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,4254,
-4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,
-4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,
-4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298,4299,
-4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,
-4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,
-4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,
-4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,
-4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,
-4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,
-4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,
-4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,4419,
-4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,
-4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,
-4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,
-4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,
-4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,
-4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,
-4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,
-4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,
-4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,
-4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,
-4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,4584,
-4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,
-4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,
-4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,4629,
-4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,
-4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,4659,
-4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,4674,
-4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,4689,
-4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,4704,
-4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,
-4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,
-4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,4749,
-4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,
-4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,
-4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,4794,
-4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,4809,
-4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,4824,
-4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,
-4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,
-4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,
-4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883,4884,
-4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,
-4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,
-4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,
-4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,
-4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,4959,
-4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973,4974,
-4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,
-4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,5004,
-5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,5019,
-5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,
-5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,
-5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,
-5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,
-5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,
-5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,5109,
-5110,5111,5104,5105,5106,5107,5108,5109,5118,5119,5120,5121,5122,5123,5124,
-5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,5139,
-5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,5154,
-5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,
-5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,5184,
-5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,
-5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,5214,
-5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,
-5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,
-5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,
-5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,
-5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,
-5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,
-5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,
-5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,5334,
-5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,5349,
-5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,
-5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,
-5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,
-5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,
-5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,
-5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,
-5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,
-5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,
-5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,
-5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,
-5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,
-5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,
-5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,5544,
-5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,
-5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,
-5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,
-5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,
-5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,
-5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,
-5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,
-5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,
-5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,
-5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,
-5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,
-5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,
-5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,
-5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,
-5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,
-5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,
-5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,
-5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,
-5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,
-5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,
-5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,
-5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,
-5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,
-5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,
-5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,
-5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,
-5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,
-5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,
-5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,
-5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,
-5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,
-6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,
-6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,
-6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,
-6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,
-6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,
-6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,
-6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,
-6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,
-6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,
-6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,
-6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,
-6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,
-6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,
-6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,
-6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,
-6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,
-6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6264,
-6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,6279,
-6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,
-6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,
-6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,6324,
-6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,6339,
-6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,
-6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,6369,
-6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,
-6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,
-6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,
-6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,
-6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6444,
-6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,
-6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474,
-6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,
-6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,
-6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,
-6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,
-6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,
-6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,
-6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,
-6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,
-6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,
-6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,
-6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,6639,
-6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,
-6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,
-6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,
-6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,
-6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,
-6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,
-6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,
-6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,
-6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,
-6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,6789,
-6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,
-6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,
-6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,
-6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,6849,
-6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864,
-6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,6879,
-6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894,
-6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,6909,
-6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,
-6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,6939,
-6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,6954,
-6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968,6969,
-6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984,
-6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,6999,
-7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,7014,
-7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029,
-7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,
-7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,
-7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,
-7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,
-7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,
-7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,
-7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,
-7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,
-7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,
-7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,
-7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,
-7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,
-7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,
-7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,
-7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,7254,
-7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,
-7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,7284,
-7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,1042,1044,1054,1057,
-1058,1058,1066,1122,42570L,7305,7306,7307,7308,7309,7310,7311,7312,7313,
-7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,7328,
-7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343,
-7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,
-7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,
-7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,
-7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,
-7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,
-7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,
-7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,7448,
-7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,
-7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,
-7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,
-7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,
-7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,
-7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,
-7539,7540,7541,7542,7543,7544,42877L,7546,7547,7548,11363,7550,7551,7552,
-7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,
-7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,
-7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,
-7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,
-7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,
-7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,
-7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,
-7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,7671,7672,
-7673,7674,7675,7676,7677,7678,7679,7680,7680,7682,7682,7684,7684,7686,7686,
-7688,7688,7690,7690,7692,7692,7694,7694,7696,7696,7698,7698,7700,7700,7702,
-7702,7704,7704,7706,7706,7708,7708,7710,7710,7712,7712,7714,7714,7716,7716,
-7718,7718,7720,7720,7722,7722,7724,7724,7726,7726,7728,7728,7730,7730,7732,
-7732,7734,7734,7736,7736,7738,7738,7740,7740,7742,7742,7744,7744,7746,7746,
-7748,7748,7750,7750,7752,7752,7754,7754,7756,7756,7758,7758,7760,7760,7762,
-7762,7764,7764,7766,7766,7768,7768,7770,7770,7772,7772,7774,7774,7776,7776,
-7778,7778,7780,7780,7782,7782,7784,7784,7786,7786,7788,7788,7790,7790,7792,
-7792,7794,7794,7796,7796,7798,7798,7800,7800,7802,7802,7804,7804,7806,7806,
-7808,7808,7810,7810,7812,7812,7814,7814,7816,7816,7818,7818,7820,7820,7822,
-7822,7824,7824,7826,7826,7828,7828,7830,7831,7832,7833,7834,7776,7836,7837,
-7838,7839,7840,7840,7842,7842,7844,7844,7846,7846,7848,7848,7850,7850,7852,
-7852,7854,7854,7856,7856,7858,7858,7860,7860,7862,7862,7864,7864,7866,7866,
-7868,7868,7870,7870,7872,7872,7874,7874,7876,7876,7878,7878,7880,7880,7882,
-7882,7884,7884,7886,7886,7888,7888,7890,7890,7892,7892,7894,7894,7896,7896,
-7898,7898,7900,7900,7902,7902,7904,7904,7906,7906,7908,7908,7910,7910,7912,
-7912,7914,7914,7916,7916,7918,7918,7920,7920,7922,7922,7924,7924,7926,7926,
-7928,7928,7930,7930,7932,7932,7934,7934,7944,7945,7946,7947,7948,7949,7950,
-7951,7944,7945,7946,7947,7948,7949,7950,7951,7960,7961,7962,7963,7964,7965,
-7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7976,7977,7978,7979,7980,
-7981,7982,7983,7976,7977,7978,7979,7980,7981,7982,7983,7992,7993,7994,7995,
-7996,7997,7998,7999,7992,7993,7994,7995,7996,7997,7998,7999,8008,8009,8010,
-8011,8012,8013,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,8025,
-8018,8027,8020,8029,8022,8031,8024,8025,8026,8027,8028,8029,8030,8031,8040,
-8041,8042,8043,8044,8045,8046,8047,8040,8041,8042,8043,8044,8045,8046,8047,
-8122,8123,8136,8137,8138,8139,8154,8155,8184,8185,8170,8171,8186,8187,8062,
-8063,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,
-8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,
-8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,
-8108,8109,8110,8111,8120,8121,8114,8115,8116,8117,8118,8119,8120,8121,8122,
-8123,8124,8125,921,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,
-8138,8139,8140,8141,8142,8143,8152,8153,8146,8147,8148,8149,8150,8151,8152,
-8153,8154,8155,8156,8157,8158,8159,8168,8169,8162,8163,8164,8172,8166,8167,
-8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,8182,
-8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,
-8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,
-8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,
-8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,
-8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,
-8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,
-8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,
-8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,
-8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,
-8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,
-8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,
-8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,
-8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,
-8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,
-8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405,8406,8407,
-8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422,
-8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,8435,8436,8437,
-8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,8450,8451,8452,
-8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,
-8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,
-8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,
-8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,8512,
-8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8498,8527,
-8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,
-8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,
-8558,8559,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,
-8557,8558,8559,8576,8577,8578,8579,8579,8581,8582,8583,8584,8585,8586,8587,
-8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,
-8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,
-8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629,8630,8631,8632,
-8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,8645,8646,8647,
-8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,8660,8661,8662,
-8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,8675,8676,8677,
-8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,
-8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,
-8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,
-8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,
-8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749,8750,8751,8752,
-8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,8765,8766,8767,
-8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780,8781,8782,
-8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,8793,8794,8795,8796,8797,
-8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809,8810,8811,8812,
-8813,8814,8815,8816,8817,8818,8819,8820,8821,8822,8823,8824,8825,8826,8827,
-8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839,8840,8841,8842,
-8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857,
-8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870,8871,8872,
-8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,8885,8886,8887,
-8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901,8902,
-8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917,
-8918,8919,8920,8921,8922,8923,8924,8925,8926,8927,8928,8929,8930,8931,8932,
-8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,8945,8946,8947,
-8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962,
-8963,8964,8965,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977,
-8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,
-8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,
-9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022,
-9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,
-9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,
-9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,9065,9066,9067,
-9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,
-9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,
-9098,9099,9100,9101,9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,
-9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,
-9128,9129,9130,9131,9132,9133,9134,9135,9136,9137,9138,9139,9140,9141,9142,
-9143,9144,9145,9146,9147,9148,9149,9150,9151,9152,9153,9154,9155,9156,9157,
-9158,9159,9160,9161,9162,9163,9164,9165,9166,9167,9168,9169,9170,9171,9172,
-9173,9174,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184,9185,9186,9187,
-9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199,9200,9201,9202,
-9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214,9215,9216,9217,
-9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,9230,9231,9232,
-9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9246,9247,
-9248,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,9260,9261,9262,
-9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,9275,9276,9277,
-9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,9290,9291,9292,
-9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,9305,9306,9307,
-9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,
-9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334,9335,9336,9337,
-9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9352,
-9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,9365,9366,9367,
-9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382,
-9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,
-9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,
-9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9398,9399,9400,9401,
-9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,9413,9414,9415,9416,
-9417,9418,9419,9420,9421,9422,9423,9450,9451,9452,9453,9454,9455,9456,9457,
-9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,
-9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,
-9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,
-9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,
-9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,
-9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,
-9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,
-9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,
-9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,9590,9591,9592,
-9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604,9605,9606,9607,
-9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619,9620,9621,9622,
-9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,9635,9636,9637,
-9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,9650,9651,9652,
-9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664,9665,9666,9667,
-9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,9680,9681,9682,
-9683,9684,9685,9686,9687,9688,9689,9690,9691,9692,9693,9694,9695,9696,9697,
-9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709,9710,9711,9712,
-9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,
-9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739,9740,9741,9742,
-9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,
-9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,
-9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,
-9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,
-9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,
-9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,
-9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,
-9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,
-9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,
-9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,9890,9891,9892,
-9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,
-9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,
-9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,
-9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,
-9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,
-9968,9969,9970,9971,9972,9973,9974,9975,9976,9977,9978,9979,9980,9981,9982,
-9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,
-9998,9999,10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,
-10010,10011,10012,10013,10014,10015,10016,10017,10018,10019,10020,10021,
-10022,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033,
-10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,
-10046,10047,10048,10049,10050,10051,10052,10053,10054,10055,10056,10057,
-10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,10068,10069,
-10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,
-10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,10093,
-10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,10104,10105,
-10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,10116,10117,
-10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128,10129,
-10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,10141,
-10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,10152,10153,
-10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,10164,10165,
-10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,
-10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,
-10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,10200,10201,
-10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,
-10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,
-10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,
-10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,10248,10249,
-10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,10260,10261,
-10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,
-10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,
-10286,10287,10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,
-10298,10299,10300,10301,10302,10303,10304,10305,10306,10307,10308,10309,
-10310,10311,10312,10313,10314,10315,10316,10317,10318,10319,10320,10321,
-10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,
-10334,10335,10336,10337,10338,10339,10340,10341,10342,10343,10344,10345,
-10346,10347,10348,10349,10350,10351,10352,10353,10354,10355,10356,10357,
-10358,10359,10360,10361,10362,10363,10364,10365,10366,10367,10368,10369,
-10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,10380,10381,
-10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,10393,
-10394,10395,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,
-10406,10407,10408,10409,10410,10411,10412,10413,10414,10415,10416,10417,
-10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,10428,10429,
-10430,10431,10432,10433,10434,10435,10436,10437,10438,10439,10440,10441,
-10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,10452,10453,
-10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,
-10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,
-10478,10479,10480,10481,10482,10483,10484,10485,10486,10487,10488,10489,
-10490,10491,10492,10493,10494,10495,10496,10497,10498,10499,10500,10501,
-10502,10503,10504,10505,10506,10507,10508,10509,10510,10511,10512,10513,
-10514,10515,10516,10517,10518,10519,10520,10521,10522,10523,10524,10525,
-10526,10527,10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,
-10538,10539,10540,10541,10542,10543,10544,10545,10546,10547,10548,10549,
-10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,10560,10561,
-10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,10573,
-10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,
-10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,
-10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,10608,10609,
-10610,10611,10612,10613,10614,10615,10616,10617,10618,10619,10620,10621,
-10622,10623,10624,10625,10626,10627,10628,10629,10630,10631,10632,10633,
-10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,
-10646,10647,10648,10649,10650,10651,10652,10653,10654,10655,10656,10657,
-10658,10659,10660,10661,10662,10663,10664,10665,10666,10667,10668,10669,
-10670,10671,10672,10673,10674,10675,10676,10677,10678,10679,10680,10681,
-10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692,10693,
-10694,10695,10696,10697,10698,10699,10700,10701,10702,10703,10704,10705,
-10706,10707,10708,10709,10710,10711,10712,10713,10714,10715,10716,10717,
-10718,10719,10720,10721,10722,10723,10724,10725,10726,10727,10728,10729,
-10730,10731,10732,10733,10734,10735,10736,10737,10738,10739,10740,10741,
-10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,10752,10753,
-10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,10764,10765,
-10766,10767,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,
-10778,10779,10780,10781,10782,10783,10784,10785,10786,10787,10788,10789,
-10790,10791,10792,10793,10794,10795,10796,10797,10798,10799,10800,10801,
-10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812,10813,
-10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,
-10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836,10837,
-10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,10848,10849,
-10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,
-10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,
-10874,10875,10876,10877,10878,10879,10880,10881,10882,10883,10884,10885,
-10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,10896,10897,
-10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,10908,10909,
-10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,10920,10921,
-10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,10933,
-10934,10935,10936,10937,10938,10939,10940,10941,10942,10943,10944,10945,
-10946,10947,10948,10949,10950,10951,10952,10953,10954,10955,10956,10957,
-10958,10959,10960,10961,10962,10963,10964,10965,10966,10967,10968,10969,
-10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,
-10982,10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,
-10994,10995,10996,10997,10998,10999,11000,11001,11002,11003,11004,11005,
-11006,11007,11008,11009,11010,11011,11012,11013,11014,11015,11016,11017,
-11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029,
-11030,11031,11032,11033,11034,11035,11036,11037,11038,11039,11040,11041,
-11042,11043,11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,
-11054,11055,11056,11057,11058,11059,11060,11061,11062,11063,11064,11065,
-11066,11067,11068,11069,11070,11071,11072,11073,11074,11075,11076,11077,
-11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088,11089,
-11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,
-11102,11103,11104,11105,11106,11107,11108,11109,11110,11111,11112,11113,
-11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,11124,11125,
-11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,11136,11137,
-11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,
-11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,
-11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,11172,11173,
-11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,11184,11185,
-11186,11187,11188,11189,11190,11191,11192,11193,11194,11195,11196,11197,
-11198,11199,11200,11201,11202,11203,11204,11205,11206,11207,11208,11209,
-11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,
-11222,11223,11224,11225,11226,11227,11228,11229,11230,11231,11232,11233,
-11234,11235,11236,11237,11238,11239,11240,11241,11242,11243,11244,11245,
-11246,11247,11248,11249,11250,11251,11252,11253,11254,11255,11256,11257,
-11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,
-11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,11280,11281,
-11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,
-11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,
-11306,11307,11308,11309,11310,11311,11264,11265,11266,11267,11268,11269,
-11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,11280,11281,
-11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,
-11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,
-11306,11307,11308,11309,11310,11359,11360,11360,11362,11363,11364,570,574,
-11367,11367,11369,11369,11371,11371,11373,11374,11375,11376,11377,11378,
-11378,11380,11381,11381,11383,11384,11385,11386,11387,11388,11389,11390,
-11391,11392,11392,11394,11394,11396,11396,11398,11398,11400,11400,11402,
-11402,11404,11404,11406,11406,11408,11408,11410,11410,11412,11412,11414,
-11414,11416,11416,11418,11418,11420,11420,11422,11422,11424,11424,11426,
-11426,11428,11428,11430,11430,11432,11432,11434,11434,11436,11436,11438,
-11438,11440,11440,11442,11442,11444,11444,11446,11446,11448,11448,11450,
-11450,11452,11452,11454,11454,11456,11456,11458,11458,11460,11460,11462,
-11462,11464,11464,11466,11466,11468,11468,11470,11470,11472,11472,11474,
-11474,11476,11476,11478,11478,11480,11480,11482,11482,11484,11484,11486,
-11486,11488,11488,11490,11490,11492,11493,11494,11495,11496,11497,11498,
-11499,11499,11501,11501,11503,11504,11505,11506,11506,11508,11509,11510,
-11511,11512,11513,11514,11515,11516,11517,11518,11519,4256,4257,4258,4259,
-4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,
-4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,
-4290,4291,4292,4293,11558,4295,11560,11561,11562,11563,11564,4301,11566,
-11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,
-11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,
-11591,11592,11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,
-11603,11604,11605,11606,11607,11608,11609,11610,11611,11612,11613,11614,
-11615,11616,11617,11618,11619,11620,11621,11622,11623,11624,11625,11626,
-11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638,
-11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,
-11651,11652,11653,11654,11655,11656,11657,11658,11659,11660,11661,11662,
-11663,11664,11665,11666,11667,11668,11669,11670,11671,11672,11673,11674,
-11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685,11686,
-11687,11688,11689,11690,11691,11692,11693,11694,11695,11696,11697,11698,
-11699,11700,11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,
-11711,11712,11713,11714,11715,11716,11717,11718,11719,11720,11721,11722,
-11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,
-11735,11736,11737,11738,11739,11740,11741,11742,11743,11744,11745,11746,
-11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,
-11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,
-11771,11772,11773,11774,11775,11776,11777,11778,11779,11780,11781,11782,
-11783,11784,11785,11786,11787,11788,11789,11790,11791,11792,11793,11794,
-11795,11796,11797,11798,11799,11800,11801,11802,11803,11804,11805,11806,
-11807,11808,11809,11810,11811,11812,11813,11814,11815,11816,11817,11818,
-11819,11820,11821,11822,11823,11824,11825,11826,11827,11828,11829,11830,
-11831,11832,11833,11834,11835,11836,11837,11838,11839,11840,11841,11842,
-11843,11844,11845,11846,11847,11848,11849,11850,11851,11852,11853,11854,
-11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866,
-11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,
-11879,11880,11881,11882,11883,11884,11885,11886,11887,11888,11889,11890,
-11891,11892,11893,11894,11895,11896,11897,11898,11899,11900,11901,11902,
-11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913,11914,
-11915,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,
-11927,11928,11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,
-11939,11940,11941,11942,11943,11944,11945,11946,11947,11948,11949,11950,
-11951,11952,11953,11954,11955,11956,11957,11958,11959,11960,11961,11962,
-11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,
-11975,11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,
-11987,11988,11989,11990,11991,11992,11993,11994,11995,11996,11997,11998,
-11999,12000,12001,12002,12003,12004,12005,12006,12007,12008,12009,12010,
-12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021,12022,
-12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,
-12035,12036,12037,12038,12039,12040,12041,12042,12043,12044,12045,12046,
-12047,12048,12049,12050,12051,12052,12053,12054,12055,12056,12057,12058,
-12059,12060,12061,12062,12063,12064,12065,12066,12067,12068,12069,12070,
-12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,
-12083,12084,12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,
-12095,12096,12097,12098,12099,12100,12101,12102,12103,12104,12105,12106,
-12107,12108,12109,12110,12111,12112,12113,12114,12115,12116,12117,12118,
-12119,12120,12121,12122,12123,12124,12125,12126,12127,12128,12129,12130,
-12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,
-12143,12144,12145,12146,12147,12148,12149,12150,12151,12152,12153,12154,
-12155,12156,12157,12158,12159,12160,12161,12162,12163,12164,12165,12166,
-12167,12168,12169,12170,12171,12172,12173,12174,12175,12176,12177,12178,
-12179,12180,12181,12182,12183,12184,12185,12186,12187,12188,12189,12190,
-12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,
-12203,12204,12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,
-12215,12216,12217,12218,12219,12220,12221,12222,12223,12224,12225,12226,
-12227,12228,12229,12230,12231,12232,12233,12234,12235,12236,12237,12238,
-12239,12240,12241,12242,12243,12244,12245,12246,12247,12248,12249,12250,
-12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,
-12263,12264,12265,12266,12267,12268,12269,12270,12271,12272,12273,12274,
-12275,12276,12277,12278,12279,12280,12281,12282,12283,12284,12285,12286,
-12287,12288,12289,12290,12291,12292,12293,12294,12295,12296,12297,12298,
-12299,12300,12301,12302,12303,12304,12305,12306,12307,12308,12309,12310,
-12311,12312,12313,12314,12315,12316,12317,12318,12319,12320,12321,12322,
-12323,12324,12325,12326,12327,12328,12329,12330,12331,12332,12333,12334,
-12335,12336,12337,12338,12339,12340,12341,12342,12343,12344,12345,12346,
-12347,12348,12349,12350,12351,12352,12353,12354,12355,12356,12357,12358,
-12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,
-12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,
-12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,
-12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,
-12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
-12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
-12431,12432,12433,12434,12435,12436,12437,12438,12439,12440,12441,12442,
-12443,12444,12445,12446,12447,12448,12449,12450,12451,12452,12453,12454,
-12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,
-12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,
-12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,
-12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,
-12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,
-12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,
-12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,
-12539,12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,
-12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,
-12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,
-12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,12586,
-12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,
-12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,
-12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,12622,
-12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,
-12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,
-12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,
-12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,
-12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,
-12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,
-12695,12696,12697,12698,12699,12700,12701,12702,12703,12704,12705,12706,
-12707,12708,12709,12710,12711,12712,12713,12714,12715,12716,12717,12718,
-12719,12720,12721,12722,12723,12724,12725,12726,12727,12728,12729,12730,
-12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742,
-12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,
-12755,12756,12757,12758,12759,12760,12761,12762,12763,12764,12765,12766,
-12767,12768,12769,12770,12771,12772,12773,12774,12775,12776,12777,12778,
-12779,12780,12781,12782,12783,12784,12785,12786,12787,12788,12789,12790,
-12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,
-12803,12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,
-12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,12825,12826,
-12827,12828,12829,12830,12831,12832,12833,12834,12835,12836,12837,12838,
-12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849,12850,
-12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,12862,
-12863,12864,12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,
-12875,12876,12877,12878,12879,12880,12881,12882,12883,12884,12885,12886,
-12887,12888,12889,12890,12891,12892,12893,12894,12895,12896,12897,12898,
-12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,
-12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,
-12923,12924,12925,12926,12927,12928,12929,12930,12931,12932,12933,12934,
-12935,12936,12937,12938,12939,12940,12941,12942,12943,12944,12945,12946,
-12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,12957,12958,
-12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,
-12971,12972,12973,12974,12975,12976,12977,12978,12979,12980,12981,12982,
-12983,12984,12985,12986,12987,12988,12989,12990,12991,12992,12993,12994,
-12995,12996,12997,12998,12999,13000,13001,13002,13003,13004,13005,13006,
-13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018,
-13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,
-13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,
-13043,13044,13045,13046,13047,13048,13049,13050,13051,13052,13053,13054,
-13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065,13066,
-13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,
-13079,13080,13081,13082,13083,13084,13085,13086,13087,13088,13089,13090,
-13091,13092,13093,13094,13095,13096,13097,13098,13099,13100,13101,13102,
-13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113,13114,
-13115,13116,13117,13118,13119,13120,13121,13122,13123,13124,13125,13126,
-13127,13128,13129,13130,13131,13132,13133,13134,13135,13136,13137,13138,
-13139,13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,
-13151,13152,13153,13154,13155,13156,13157,13158,13159,13160,13161,13162,
-13163,13164,13165,13166,13167,13168,13169,13170,13171,13172,13173,13174,
-13175,13176,13177,13178,13179,13180,13181,13182,13183,13184,13185,13186,
-13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,
-13199,13200,13201,13202,13203,13204,13205,13206,13207,13208,13209,13210,
-13211,13212,13213,13214,13215,13216,13217,13218,13219,13220,13221,13222,
-13223,13224,13225,13226,13227,13228,13229,13230,13231,13232,13233,13234,
-13235,13236,13237,13238,13239,13240,13241,13242,13243,13244,13245,13246,
-13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,
-13259,13260,13261,13262,13263,13264,13265,13266,13267,13268,13269,13270,
-13271,13272,13273,13274,13275,13276,13277,13278,13279,13280,13281,13282,
-13283,13284,13285,13286,13287,13288,13289,13290,13291,13292,13293,13294,
-13295,13296,13297,13298,13299,13300,13301,13302,13303,13304,13305,13306,
-13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,
-13319,13320,13321,13322,13323,13324,13325,13326,13327,13328,13329,13330,
-13331,13332,13333,13334,13335,13336,13337,13338,13339,13340,13341,13342,
-13343,13344,13345,13346,13347,13348,13349,13350,13351,13352,13353,13354,
-13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,
-13367,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,
-13379,13380,13381,13382,13383,13384,13385,13386,13387,13388,13389,13390,
-13391,13392,13393,13394,13395,13396,13397,13398,13399,13400,13401,13402,
-13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414,
-13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,
-13427,13428,13429,13430,13431,13432,13433,13434,13435,13436,13437,13438,
-13439,13440,13441,13442,13443,13444,13445,13446,13447,13448,13449,13450,
-13451,13452,13453,13454,13455,13456,13457,13458,13459,13460,13461,13462,
-13463,13464,13465,13466,13467,13468,13469,13470,13471,13472,13473,13474,
-13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,
-13487,13488,13489,13490,13491,13492,13493,13494,13495,13496,13497,13498,
-13499,13500,13501,13502,13503,13504,13505,13506,13507,13508,13509,13510,
-13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522,
-13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,
-13535,13536,13537,13538,13539,13540,13541,13542,13543,13544,13545,13546,
-13547,13548,13549,13550,13551,13552,13553,13554,13555,13556,13557,13558,
-13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570,
-13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,
-13583,13584,13585,13586,13587,13588,13589,13590,13591,13592,13593,13594,
-13595,13596,13597,13598,13599,13600,13601,13602,13603,13604,13605,13606,
-13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618,
-13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,
-13631,13632,13633,13634,13635,13636,13637,13638,13639,13640,13641,13642,
-13643,13644,13645,13646,13647,13648,13649,13650,13651,13652,13653,13654,
-13655,13656,13657,13658,13659,13660,13661,13662,13663,13664,13665,13666,
-13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,
-13679,13680,13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,
-13691,13692,13693,13694,13695,13696,13697,13698,13699,13700,13701,13702,
-13703,13704,13705,13706,13707,13708,13709,13710,13711,13712,13713,13714,
-13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,
-13727,13728,13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,
-13739,13740,13741,13742,13743,13744,13745,13746,13747,13748,13749,13750,
-13751,13752,13753,13754,13755,13756,13757,13758,13759,13760,13761,13762,
-13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,
-13775,13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,
-13787,13788,13789,13790,13791,13792,13793,13794,13795,13796,13797,13798,
-13799,13800,13801,13802,13803,13804,13805,13806,13807,13808,13809,13810,
-13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,
-13823,13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,
-13835,13836,13837,13838,13839,13840,13841,13842,13843,13844,13845,13846,
-13847,13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,
-13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,
-13871,13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,
-13883,13884,13885,13886,13887,13888,13889,13890,13891,13892,13893,13894,
-13895,13896,13897,13898,13899,13900,13901,13902,13903,13904,13905,13906,
-13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,
-13919,13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,
-13931,13932,13933,13934,13935,13936,13937,13938,13939,13940,13941,13942,
-13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,
-13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,
-13967,13968,13969,13970,13971,13972,13973,13974,13975,13976,13977,13978,
-13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,
-13991,13992,13993,13994,13995,13996,13997,13998,13999,14000,14001,14002,
-14003,14004,14005,14006,14007,14008,14009,14010,14011,14012,14013,14014,
-14015,14016,14017,14018,14019,14020,14021,14022,14023,14024,14025,14026,
-14027,14028,14029,14030,14031,14032,14033,14034,14035,14036,14037,14038,
-14039,14040,14041,14042,14043,14044,14045,14046,14047,14048,14049,14050,
-14051,14052,14053,14054,14055,14056,14057,14058,14059,14060,14061,14062,
-14063,14064,14065,14066,14067,14068,14069,14070,14071,14072,14073,14074,
-14075,14076,14077,14078,14079,14080,14081,14082,14083,14084,14085,14086,
-14087,14088,14089,14090,14091,14092,14093,14094,14095,14096,14097,14098,
-14099,14100,14101,14102,14103,14104,14105,14106,14107,14108,14109,14110,
-14111,14112,14113,14114,14115,14116,14117,14118,14119,14120,14121,14122,
-14123,14124,14125,14126,14127,14128,14129,14130,14131,14132,14133,14134,
-14135,14136,14137,14138,14139,14140,14141,14142,14143,14144,14145,14146,
-14147,14148,14149,14150,14151,14152,14153,14154,14155,14156,14157,14158,
-14159,14160,14161,14162,14163,14164,14165,14166,14167,14168,14169,14170,
-14171,14172,14173,14174,14175,14176,14177,14178,14179,14180,14181,14182,
-14183,14184,14185,14186,14187,14188,14189,14190,14191,14192,14193,14194,
-14195,14196,14197,14198,14199,14200,14201,14202,14203,14204,14205,14206,
-14207,14208,14209,14210,14211,14212,14213,14214,14215,14216,14217,14218,
-14219,14220,14221,14222,14223,14224,14225,14226,14227,14228,14229,14230,
-14231,14232,14233,14234,14235,14236,14237,14238,14239,14240,14241,14242,
-14243,14244,14245,14246,14247,14248,14249,14250,14251,14252,14253,14254,
-14255,14256,14257,14258,14259,14260,14261,14262,14263,14264,14265,14266,
-14267,14268,14269,14270,14271,14272,14273,14274,14275,14276,14277,14278,
-14279,14280,14281,14282,14283,14284,14285,14286,14287,14288,14289,14290,
-14291,14292,14293,14294,14295,14296,14297,14298,14299,14300,14301,14302,
-14303,14304,14305,14306,14307,14308,14309,14310,14311,14312,14313,14314,
-14315,14316,14317,14318,14319,14320,14321,14322,14323,14324,14325,14326,
-14327,14328,14329,14330,14331,14332,14333,14334,14335,14336,14337,14338,
-14339,14340,14341,14342,14343,14344,14345,14346,14347,14348,14349,14350,
-14351,14352,14353,14354,14355,14356,14357,14358,14359,14360,14361,14362,
-14363,14364,14365,14366,14367,14368,14369,14370,14371,14372,14373,14374,
-14375,14376,14377,14378,14379,14380,14381,14382,14383,14384,14385,14386,
-14387,14388,14389,14390,14391,14392,14393,14394,14395,14396,14397,14398,
-14399,14400,14401,14402,14403,14404,14405,14406,14407,14408,14409,14410,
-14411,14412,14413,14414,14415,14416,14417,14418,14419,14420,14421,14422,
-14423,14424,14425,14426,14427,14428,14429,14430,14431,14432,14433,14434,
-14435,14436,14437,14438,14439,14440,14441,14442,14443,14444,14445,14446,
-14447,14448,14449,14450,14451,14452,14453,14454,14455,14456,14457,14458,
-14459,14460,14461,14462,14463,14464,14465,14466,14467,14468,14469,14470,
-14471,14472,14473,14474,14475,14476,14477,14478,14479,14480,14481,14482,
-14483,14484,14485,14486,14487,14488,14489,14490,14491,14492,14493,14494,
-14495,14496,14497,14498,14499,14500,14501,14502,14503,14504,14505,14506,
-14507,14508,14509,14510,14511,14512,14513,14514,14515,14516,14517,14518,
-14519,14520,14521,14522,14523,14524,14525,14526,14527,14528,14529,14530,
-14531,14532,14533,14534,14535,14536,14537,14538,14539,14540,14541,14542,
-14543,14544,14545,14546,14547,14548,14549,14550,14551,14552,14553,14554,
-14555,14556,14557,14558,14559,14560,14561,14562,14563,14564,14565,14566,
-14567,14568,14569,14570,14571,14572,14573,14574,14575,14576,14577,14578,
-14579,14580,14581,14582,14583,14584,14585,14586,14587,14588,14589,14590,
-14591,14592,14593,14594,14595,14596,14597,14598,14599,14600,14601,14602,
-14603,14604,14605,14606,14607,14608,14609,14610,14611,14612,14613,14614,
-14615,14616,14617,14618,14619,14620,14621,14622,14623,14624,14625,14626,
-14627,14628,14629,14630,14631,14632,14633,14634,14635,14636,14637,14638,
-14639,14640,14641,14642,14643,14644,14645,14646,14647,14648,14649,14650,
-14651,14652,14653,14654,14655,14656,14657,14658,14659,14660,14661,14662,
-14663,14664,14665,14666,14667,14668,14669,14670,14671,14672,14673,14674,
-14675,14676,14677,14678,14679,14680,14681,14682,14683,14684,14685,14686,
-14687,14688,14689,14690,14691,14692,14693,14694,14695,14696,14697,14698,
-14699,14700,14701,14702,14703,14704,14705,14706,14707,14708,14709,14710,
-14711,14712,14713,14714,14715,14716,14717,14718,14719,14720,14721,14722,
-14723,14724,14725,14726,14727,14728,14729,14730,14731,14732,14733,14734,
-14735,14736,14737,14738,14739,14740,14741,14742,14743,14744,14745,14746,
-14747,14748,14749,14750,14751,14752,14753,14754,14755,14756,14757,14758,
-14759,14760,14761,14762,14763,14764,14765,14766,14767,14768,14769,14770,
-14771,14772,14773,14774,14775,14776,14777,14778,14779,14780,14781,14782,
-14783,14784,14785,14786,14787,14788,14789,14790,14791,14792,14793,14794,
-14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,
-14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14818,
-14819,14820,14821,14822,14823,14824,14825,14826,14827,14828,14829,14830,
-14831,14832,14833,14834,14835,14836,14837,14838,14839,14840,14841,14842,
-14843,14844,14845,14846,14847,14848,14849,14850,14851,14852,14853,14854,
-14855,14856,14857,14858,14859,14860,14861,14862,14863,14864,14865,14866,
-14867,14868,14869,14870,14871,14872,14873,14874,14875,14876,14877,14878,
-14879,14880,14881,14882,14883,14884,14885,14886,14887,14888,14889,14890,
-14891,14892,14893,14894,14895,14896,14897,14898,14899,14900,14901,14902,
-14903,14904,14905,14906,14907,14908,14909,14910,14911,14912,14913,14914,
-14915,14916,14917,14918,14919,14920,14921,14922,14923,14924,14925,14926,
-14927,14928,14929,14930,14931,14932,14933,14934,14935,14936,14937,14938,
-14939,14940,14941,14942,14943,14944,14945,14946,14947,14948,14949,14950,
-14951,14952,14953,14954,14955,14956,14957,14958,14959,14960,14961,14962,
-14963,14964,14965,14966,14967,14968,14969,14970,14971,14972,14973,14974,
-14975,14976,14977,14978,14979,14980,14981,14982,14983,14984,14985,14986,
-14987,14988,14989,14990,14991,14992,14993,14994,14995,14996,14997,14998,
-14999,15000,15001,15002,15003,15004,15005,15006,15007,15008,15009,15010,
-15011,15012,15013,15014,15015,15016,15017,15018,15019,15020,15021,15022,
-15023,15024,15025,15026,15027,15028,15029,15030,15031,15032,15033,15034,
-15035,15036,15037,15038,15039,15040,15041,15042,15043,15044,15045,15046,
-15047,15048,15049,15050,15051,15052,15053,15054,15055,15056,15057,15058,
-15059,15060,15061,15062,15063,15064,15065,15066,15067,15068,15069,15070,
-15071,15072,15073,15074,15075,15076,15077,15078,15079,15080,15081,15082,
-15083,15084,15085,15086,15087,15088,15089,15090,15091,15092,15093,15094,
-15095,15096,15097,15098,15099,15100,15101,15102,15103,15104,15105,15106,
-15107,15108,15109,15110,15111,15112,15113,15114,15115,15116,15117,15118,
-15119,15120,15121,15122,15123,15124,15125,15126,15127,15128,15129,15130,
-15131,15132,15133,15134,15135,15136,15137,15138,15139,15140,15141,15142,
-15143,15144,15145,15146,15147,15148,15149,15150,15151,15152,15153,15154,
-15155,15156,15157,15158,15159,15160,15161,15162,15163,15164,15165,15166,
-15167,15168,15169,15170,15171,15172,15173,15174,15175,15176,15177,15178,
-15179,15180,15181,15182,15183,15184,15185,15186,15187,15188,15189,15190,
-15191,15192,15193,15194,15195,15196,15197,15198,15199,15200,15201,15202,
-15203,15204,15205,15206,15207,15208,15209,15210,15211,15212,15213,15214,
-15215,15216,15217,15218,15219,15220,15221,15222,15223,15224,15225,15226,
-15227,15228,15229,15230,15231,15232,15233,15234,15235,15236,15237,15238,
-15239,15240,15241,15242,15243,15244,15245,15246,15247,15248,15249,15250,
-15251,15252,15253,15254,15255,15256,15257,15258,15259,15260,15261,15262,
-15263,15264,15265,15266,15267,15268,15269,15270,15271,15272,15273,15274,
-15275,15276,15277,15278,15279,15280,15281,15282,15283,15284,15285,15286,
-15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,
-15299,15300,15301,15302,15303,15304,15305,15306,15307,15308,15309,15310,
-15311,15312,15313,15314,15315,15316,15317,15318,15319,15320,15321,15322,
-15323,15324,15325,15326,15327,15328,15329,15330,15331,15332,15333,15334,
-15335,15336,15337,15338,15339,15340,15341,15342,15343,15344,15345,15346,
-15347,15348,15349,15350,15351,15352,15353,15354,15355,15356,15357,15358,
-15359,15360,15361,15362,15363,15364,15365,15366,15367,15368,15369,15370,
-15371,15372,15373,15374,15375,15376,15377,15378,15379,15380,15381,15382,
-15383,15384,15385,15386,15387,15388,15389,15390,15391,15392,15393,15394,
-15395,15396,15397,15398,15399,15400,15401,15402,15403,15404,15405,15406,
-15407,15408,15409,15410,15411,15412,15413,15414,15415,15416,15417,15418,
-15419,15420,15421,15422,15423,15424,15425,15426,15427,15428,15429,15430,
-15431,15432,15433,15434,15435,15436,15437,15438,15439,15440,15441,15442,
-15443,15444,15445,15446,15447,15448,15449,15450,15451,15452,15453,15454,
-15455,15456,15457,15458,15459,15460,15461,15462,15463,15464,15465,15466,
-15467,15468,15469,15470,15471,15472,15473,15474,15475,15476,15477,15478,
-15479,15480,15481,15482,15483,15484,15485,15486,15487,15488,15489,15490,
-15491,15492,15493,15494,15495,15496,15497,15498,15499,15500,15501,15502,
-15503,15504,15505,15506,15507,15508,15509,15510,15511,15512,15513,15514,
-15515,15516,15517,15518,15519,15520,15521,15522,15523,15524,15525,15526,
-15527,15528,15529,15530,15531,15532,15533,15534,15535,15536,15537,15538,
-15539,15540,15541,15542,15543,15544,15545,15546,15547,15548,15549,15550,
-15551,15552,15553,15554,15555,15556,15557,15558,15559,15560,15561,15562,
-15563,15564,15565,15566,15567,15568,15569,15570,15571,15572,15573,15574,
-15575,15576,15577,15578,15579,15580,15581,15582,15583,15584,15585,15586,
-15587,15588,15589,15590,15591,15592,15593,15594,15595,15596,15597,15598,
-15599,15600,15601,15602,15603,15604,15605,15606,15607,15608,15609,15610,
-15611,15612,15613,15614,15615,15616,15617,15618,15619,15620,15621,15622,
-15623,15624,15625,15626,15627,15628,15629,15630,15631,15632,15633,15634,
-15635,15636,15637,15638,15639,15640,15641,15642,15643,15644,15645,15646,
-15647,15648,15649,15650,15651,15652,15653,15654,15655,15656,15657,15658,
-15659,15660,15661,15662,15663,15664,15665,15666,15667,15668,15669,15670,
-15671,15672,15673,15674,15675,15676,15677,15678,15679,15680,15681,15682,
-15683,15684,15685,15686,15687,15688,15689,15690,15691,15692,15693,15694,
-15695,15696,15697,15698,15699,15700,15701,15702,15703,15704,15705,15706,
-15707,15708,15709,15710,15711,15712,15713,15714,15715,15716,15717,15718,
-15719,15720,15721,15722,15723,15724,15725,15726,15727,15728,15729,15730,
-15731,15732,15733,15734,15735,15736,15737,15738,15739,15740,15741,15742,
-15743,15744,15745,15746,15747,15748,15749,15750,15751,15752,15753,15754,
-15755,15756,15757,15758,15759,15760,15761,15762,15763,15764,15765,15766,
-15767,15768,15769,15770,15771,15772,15773,15774,15775,15776,15777,15778,
-15779,15780,15781,15782,15783,15784,15785,15786,15787,15788,15789,15790,
-15791,15792,15793,15794,15795,15796,15797,15798,15799,15800,15801,15802,
-15803,15804,15805,15806,15807,15808,15809,15810,15811,15812,15813,15814,
-15815,15816,15817,15818,15819,15820,15821,15822,15823,15824,15825,15826,
-15827,15828,15829,15830,15831,15832,15833,15834,15835,15836,15837,15838,
-15839,15840,15841,15842,15843,15844,15845,15846,15847,15848,15849,15850,
-15851,15852,15853,15854,15855,15856,15857,15858,15859,15860,15861,15862,
-15863,15864,15865,15866,15867,15868,15869,15870,15871,15872,15873,15874,
-15875,15876,15877,15878,15879,15880,15881,15882,15883,15884,15885,15886,
-15887,15888,15889,15890,15891,15892,15893,15894,15895,15896,15897,15898,
-15899,15900,15901,15902,15903,15904,15905,15906,15907,15908,15909,15910,
-15911,15912,15913,15914,15915,15916,15917,15918,15919,15920,15921,15922,
-15923,15924,15925,15926,15927,15928,15929,15930,15931,15932,15933,15934,
-15935,15936,15937,15938,15939,15940,15941,15942,15943,15944,15945,15946,
-15947,15948,15949,15950,15951,15952,15953,15954,15955,15956,15957,15958,
-15959,15960,15961,15962,15963,15964,15965,15966,15967,15968,15969,15970,
-15971,15972,15973,15974,15975,15976,15977,15978,15979,15980,15981,15982,
-15983,15984,15985,15986,15987,15988,15989,15990,15991,15992,15993,15994,
-15995,15996,15997,15998,15999,16000,16001,16002,16003,16004,16005,16006,
-16007,16008,16009,16010,16011,16012,16013,16014,16015,16016,16017,16018,
-16019,16020,16021,16022,16023,16024,16025,16026,16027,16028,16029,16030,
-16031,16032,16033,16034,16035,16036,16037,16038,16039,16040,16041,16042,
-16043,16044,16045,16046,16047,16048,16049,16050,16051,16052,16053,16054,
-16055,16056,16057,16058,16059,16060,16061,16062,16063,16064,16065,16066,
-16067,16068,16069,16070,16071,16072,16073,16074,16075,16076,16077,16078,
-16079,16080,16081,16082,16083,16084,16085,16086,16087,16088,16089,16090,
-16091,16092,16093,16094,16095,16096,16097,16098,16099,16100,16101,16102,
-16103,16104,16105,16106,16107,16108,16109,16110,16111,16112,16113,16114,
-16115,16116,16117,16118,16119,16120,16121,16122,16123,16124,16125,16126,
-16127,16128,16129,16130,16131,16132,16133,16134,16135,16136,16137,16138,
-16139,16140,16141,16142,16143,16144,16145,16146,16147,16148,16149,16150,
-16151,16152,16153,16154,16155,16156,16157,16158,16159,16160,16161,16162,
-16163,16164,16165,16166,16167,16168,16169,16170,16171,16172,16173,16174,
-16175,16176,16177,16178,16179,16180,16181,16182,16183,16184,16185,16186,
-16187,16188,16189,16190,16191,16192,16193,16194,16195,16196,16197,16198,
-16199,16200,16201,16202,16203,16204,16205,16206,16207,16208,16209,16210,
-16211,16212,16213,16214,16215,16216,16217,16218,16219,16220,16221,16222,
-16223,16224,16225,16226,16227,16228,16229,16230,16231,16232,16233,16234,
-16235,16236,16237,16238,16239,16240,16241,16242,16243,16244,16245,16246,
-16247,16248,16249,16250,16251,16252,16253,16254,16255,16256,16257,16258,
-16259,16260,16261,16262,16263,16264,16265,16266,16267,16268,16269,16270,
-16271,16272,16273,16274,16275,16276,16277,16278,16279,16280,16281,16282,
-16283,16284,16285,16286,16287,16288,16289,16290,16291,16292,16293,16294,
-16295,16296,16297,16298,16299,16300,16301,16302,16303,16304,16305,16306,
-16307,16308,16309,16310,16311,16312,16313,16314,16315,16316,16317,16318,
-16319,16320,16321,16322,16323,16324,16325,16326,16327,16328,16329,16330,
-16331,16332,16333,16334,16335,16336,16337,16338,16339,16340,16341,16342,
-16343,16344,16345,16346,16347,16348,16349,16350,16351,16352,16353,16354,
-16355,16356,16357,16358,16359,16360,16361,16362,16363,16364,16365,16366,
-16367,16368,16369,16370,16371,16372,16373,16374,16375,16376,16377,16378,
-16379,16380,16381,16382,16383,16384,16385,16386,16387,16388,16389,16390,
-16391,16392,16393,16394,16395,16396,16397,16398,16399,16400,16401,16402,
-16403,16404,16405,16406,16407,16408,16409,16410,16411,16412,16413,16414,
-16415,16416,16417,16418,16419,16420,16421,16422,16423,16424,16425,16426,
-16427,16428,16429,16430,16431,16432,16433,16434,16435,16436,16437,16438,
-16439,16440,16441,16442,16443,16444,16445,16446,16447,16448,16449,16450,
-16451,16452,16453,16454,16455,16456,16457,16458,16459,16460,16461,16462,
-16463,16464,16465,16466,16467,16468,16469,16470,16471,16472,16473,16474,
-16475,16476,16477,16478,16479,16480,16481,16482,16483,16484,16485,16486,
-16487,16488,16489,16490,16491,16492,16493,16494,16495,16496,16497,16498,
-16499,16500,16501,16502,16503,16504,16505,16506,16507,16508,16509,16510,
-16511,16512,16513,16514,16515,16516,16517,16518,16519,16520,16521,16522,
-16523,16524,16525,16526,16527,16528,16529,16530,16531,16532,16533,16534,
-16535,16536,16537,16538,16539,16540,16541,16542,16543,16544,16545,16546,
-16547,16548,16549,16550,16551,16552,16553,16554,16555,16556,16557,16558,
-16559,16560,16561,16562,16563,16564,16565,16566,16567,16568,16569,16570,
-16571,16572,16573,16574,16575,16576,16577,16578,16579,16580,16581,16582,
-16583,16584,16585,16586,16587,16588,16589,16590,16591,16592,16593,16594,
-16595,16596,16597,16598,16599,16600,16601,16602,16603,16604,16605,16606,
-16607,16608,16609,16610,16611,16612,16613,16614,16615,16616,16617,16618,
-16619,16620,16621,16622,16623,16624,16625,16626,16627,16628,16629,16630,
-16631,16632,16633,16634,16635,16636,16637,16638,16639,16640,16641,16642,
-16643,16644,16645,16646,16647,16648,16649,16650,16651,16652,16653,16654,
-16655,16656,16657,16658,16659,16660,16661,16662,16663,16664,16665,16666,
-16667,16668,16669,16670,16671,16672,16673,16674,16675,16676,16677,16678,
-16679,16680,16681,16682,16683,16684,16685,16686,16687,16688,16689,16690,
-16691,16692,16693,16694,16695,16696,16697,16698,16699,16700,16701,16702,
-16703,16704,16705,16706,16707,16708,16709,16710,16711,16712,16713,16714,
-16715,16716,16717,16718,16719,16720,16721,16722,16723,16724,16725,16726,
-16727,16728,16729,16730,16731,16732,16733,16734,16735,16736,16737,16738,
-16739,16740,16741,16742,16743,16744,16745,16746,16747,16748,16749,16750,
-16751,16752,16753,16754,16755,16756,16757,16758,16759,16760,16761,16762,
-16763,16764,16765,16766,16767,16768,16769,16770,16771,16772,16773,16774,
-16775,16776,16777,16778,16779,16780,16781,16782,16783,16784,16785,16786,
-16787,16788,16789,16790,16791,16792,16793,16794,16795,16796,16797,16798,
-16799,16800,16801,16802,16803,16804,16805,16806,16807,16808,16809,16810,
-16811,16812,16813,16814,16815,16816,16817,16818,16819,16820,16821,16822,
-16823,16824,16825,16826,16827,16828,16829,16830,16831,16832,16833,16834,
-16835,16836,16837,16838,16839,16840,16841,16842,16843,16844,16845,16846,
-16847,16848,16849,16850,16851,16852,16853,16854,16855,16856,16857,16858,
-16859,16860,16861,16862,16863,16864,16865,16866,16867,16868,16869,16870,
-16871,16872,16873,16874,16875,16876,16877,16878,16879,16880,16881,16882,
-16883,16884,16885,16886,16887,16888,16889,16890,16891,16892,16893,16894,
-16895,16896,16897,16898,16899,16900,16901,16902,16903,16904,16905,16906,
-16907,16908,16909,16910,16911,16912,16913,16914,16915,16916,16917,16918,
-16919,16920,16921,16922,16923,16924,16925,16926,16927,16928,16929,16930,
-16931,16932,16933,16934,16935,16936,16937,16938,16939,16940,16941,16942,
-16943,16944,16945,16946,16947,16948,16949,16950,16951,16952,16953,16954,
-16955,16956,16957,16958,16959,16960,16961,16962,16963,16964,16965,16966,
-16967,16968,16969,16970,16971,16972,16973,16974,16975,16976,16977,16978,
-16979,16980,16981,16982,16983,16984,16985,16986,16987,16988,16989,16990,
-16991,16992,16993,16994,16995,16996,16997,16998,16999,17000,17001,17002,
-17003,17004,17005,17006,17007,17008,17009,17010,17011,17012,17013,17014,
-17015,17016,17017,17018,17019,17020,17021,17022,17023,17024,17025,17026,
-17027,17028,17029,17030,17031,17032,17033,17034,17035,17036,17037,17038,
-17039,17040,17041,17042,17043,17044,17045,17046,17047,17048,17049,17050,
-17051,17052,17053,17054,17055,17056,17057,17058,17059,17060,17061,17062,
-17063,17064,17065,17066,17067,17068,17069,17070,17071,17072,17073,17074,
-17075,17076,17077,17078,17079,17080,17081,17082,17083,17084,17085,17086,
-17087,17088,17089,17090,17091,17092,17093,17094,17095,17096,17097,17098,
-17099,17100,17101,17102,17103,17104,17105,17106,17107,17108,17109,17110,
-17111,17112,17113,17114,17115,17116,17117,17118,17119,17120,17121,17122,
-17123,17124,17125,17126,17127,17128,17129,17130,17131,17132,17133,17134,
-17135,17136,17137,17138,17139,17140,17141,17142,17143,17144,17145,17146,
-17147,17148,17149,17150,17151,17152,17153,17154,17155,17156,17157,17158,
-17159,17160,17161,17162,17163,17164,17165,17166,17167,17168,17169,17170,
-17171,17172,17173,17174,17175,17176,17177,17178,17179,17180,17181,17182,
-17183,17184,17185,17186,17187,17188,17189,17190,17191,17192,17193,17194,
-17195,17196,17197,17198,17199,17200,17201,17202,17203,17204,17205,17206,
-17207,17208,17209,17210,17211,17212,17213,17214,17215,17216,17217,17218,
-17219,17220,17221,17222,17223,17224,17225,17226,17227,17228,17229,17230,
-17231,17232,17233,17234,17235,17236,17237,17238,17239,17240,17241,17242,
-17243,17244,17245,17246,17247,17248,17249,17250,17251,17252,17253,17254,
-17255,17256,17257,17258,17259,17260,17261,17262,17263,17264,17265,17266,
-17267,17268,17269,17270,17271,17272,17273,17274,17275,17276,17277,17278,
-17279,17280,17281,17282,17283,17284,17285,17286,17287,17288,17289,17290,
-17291,17292,17293,17294,17295,17296,17297,17298,17299,17300,17301,17302,
-17303,17304,17305,17306,17307,17308,17309,17310,17311,17312,17313,17314,
-17315,17316,17317,17318,17319,17320,17321,17322,17323,17324,17325,17326,
-17327,17328,17329,17330,17331,17332,17333,17334,17335,17336,17337,17338,
-17339,17340,17341,17342,17343,17344,17345,17346,17347,17348,17349,17350,
-17351,17352,17353,17354,17355,17356,17357,17358,17359,17360,17361,17362,
-17363,17364,17365,17366,17367,17368,17369,17370,17371,17372,17373,17374,
-17375,17376,17377,17378,17379,17380,17381,17382,17383,17384,17385,17386,
-17387,17388,17389,17390,17391,17392,17393,17394,17395,17396,17397,17398,
-17399,17400,17401,17402,17403,17404,17405,17406,17407,17408,17409,17410,
-17411,17412,17413,17414,17415,17416,17417,17418,17419,17420,17421,17422,
-17423,17424,17425,17426,17427,17428,17429,17430,17431,17432,17433,17434,
-17435,17436,17437,17438,17439,17440,17441,17442,17443,17444,17445,17446,
-17447,17448,17449,17450,17451,17452,17453,17454,17455,17456,17457,17458,
-17459,17460,17461,17462,17463,17464,17465,17466,17467,17468,17469,17470,
-17471,17472,17473,17474,17475,17476,17477,17478,17479,17480,17481,17482,
-17483,17484,17485,17486,17487,17488,17489,17490,17491,17492,17493,17494,
-17495,17496,17497,17498,17499,17500,17501,17502,17503,17504,17505,17506,
-17507,17508,17509,17510,17511,17512,17513,17514,17515,17516,17517,17518,
-17519,17520,17521,17522,17523,17524,17525,17526,17527,17528,17529,17530,
-17531,17532,17533,17534,17535,17536,17537,17538,17539,17540,17541,17542,
-17543,17544,17545,17546,17547,17548,17549,17550,17551,17552,17553,17554,
-17555,17556,17557,17558,17559,17560,17561,17562,17563,17564,17565,17566,
-17567,17568,17569,17570,17571,17572,17573,17574,17575,17576,17577,17578,
-17579,17580,17581,17582,17583,17584,17585,17586,17587,17588,17589,17590,
-17591,17592,17593,17594,17595,17596,17597,17598,17599,17600,17601,17602,
-17603,17604,17605,17606,17607,17608,17609,17610,17611,17612,17613,17614,
-17615,17616,17617,17618,17619,17620,17621,17622,17623,17624,17625,17626,
-17627,17628,17629,17630,17631,17632,17633,17634,17635,17636,17637,17638,
-17639,17640,17641,17642,17643,17644,17645,17646,17647,17648,17649,17650,
-17651,17652,17653,17654,17655,17656,17657,17658,17659,17660,17661,17662,
-17663,17664,17665,17666,17667,17668,17669,17670,17671,17672,17673,17674,
-17675,17676,17677,17678,17679,17680,17681,17682,17683,17684,17685,17686,
-17687,17688,17689,17690,17691,17692,17693,17694,17695,17696,17697,17698,
-17699,17700,17701,17702,17703,17704,17705,17706,17707,17708,17709,17710,
-17711,17712,17713,17714,17715,17716,17717,17718,17719,17720,17721,17722,
-17723,17724,17725,17726,17727,17728,17729,17730,17731,17732,17733,17734,
-17735,17736,17737,17738,17739,17740,17741,17742,17743,17744,17745,17746,
-17747,17748,17749,17750,17751,17752,17753,17754,17755,17756,17757,17758,
-17759,17760,17761,17762,17763,17764,17765,17766,17767,17768,17769,17770,
-17771,17772,17773,17774,17775,17776,17777,17778,17779,17780,17781,17782,
-17783,17784,17785,17786,17787,17788,17789,17790,17791,17792,17793,17794,
-17795,17796,17797,17798,17799,17800,17801,17802,17803,17804,17805,17806,
-17807,17808,17809,17810,17811,17812,17813,17814,17815,17816,17817,17818,
-17819,17820,17821,17822,17823,17824,17825,17826,17827,17828,17829,17830,
-17831,17832,17833,17834,17835,17836,17837,17838,17839,17840,17841,17842,
-17843,17844,17845,17846,17847,17848,17849,17850,17851,17852,17853,17854,
-17855,17856,17857,17858,17859,17860,17861,17862,17863,17864,17865,17866,
-17867,17868,17869,17870,17871,17872,17873,17874,17875,17876,17877,17878,
-17879,17880,17881,17882,17883,17884,17885,17886,17887,17888,17889,17890,
-17891,17892,17893,17894,17895,17896,17897,17898,17899,17900,17901,17902,
-17903,17904,17905,17906,17907,17908,17909,17910,17911,17912,17913,17914,
-17915,17916,17917,17918,17919,17920,17921,17922,17923,17924,17925,17926,
-17927,17928,17929,17930,17931,17932,17933,17934,17935,17936,17937,17938,
-17939,17940,17941,17942,17943,17944,17945,17946,17947,17948,17949,17950,
-17951,17952,17953,17954,17955,17956,17957,17958,17959,17960,17961,17962,
-17963,17964,17965,17966,17967,17968,17969,17970,17971,17972,17973,17974,
-17975,17976,17977,17978,17979,17980,17981,17982,17983,17984,17985,17986,
-17987,17988,17989,17990,17991,17992,17993,17994,17995,17996,17997,17998,
-17999,18000,18001,18002,18003,18004,18005,18006,18007,18008,18009,18010,
-18011,18012,18013,18014,18015,18016,18017,18018,18019,18020,18021,18022,
-18023,18024,18025,18026,18027,18028,18029,18030,18031,18032,18033,18034,
-18035,18036,18037,18038,18039,18040,18041,18042,18043,18044,18045,18046,
-18047,18048,18049,18050,18051,18052,18053,18054,18055,18056,18057,18058,
-18059,18060,18061,18062,18063,18064,18065,18066,18067,18068,18069,18070,
-18071,18072,18073,18074,18075,18076,18077,18078,18079,18080,18081,18082,
-18083,18084,18085,18086,18087,18088,18089,18090,18091,18092,18093,18094,
-18095,18096,18097,18098,18099,18100,18101,18102,18103,18104,18105,18106,
-18107,18108,18109,18110,18111,18112,18113,18114,18115,18116,18117,18118,
-18119,18120,18121,18122,18123,18124,18125,18126,18127,18128,18129,18130,
-18131,18132,18133,18134,18135,18136,18137,18138,18139,18140,18141,18142,
-18143,18144,18145,18146,18147,18148,18149,18150,18151,18152,18153,18154,
-18155,18156,18157,18158,18159,18160,18161,18162,18163,18164,18165,18166,
-18167,18168,18169,18170,18171,18172,18173,18174,18175,18176,18177,18178,
-18179,18180,18181,18182,18183,18184,18185,18186,18187,18188,18189,18190,
-18191,18192,18193,18194,18195,18196,18197,18198,18199,18200,18201,18202,
-18203,18204,18205,18206,18207,18208,18209,18210,18211,18212,18213,18214,
-18215,18216,18217,18218,18219,18220,18221,18222,18223,18224,18225,18226,
-18227,18228,18229,18230,18231,18232,18233,18234,18235,18236,18237,18238,
-18239,18240,18241,18242,18243,18244,18245,18246,18247,18248,18249,18250,
-18251,18252,18253,18254,18255,18256,18257,18258,18259,18260,18261,18262,
-18263,18264,18265,18266,18267,18268,18269,18270,18271,18272,18273,18274,
-18275,18276,18277,18278,18279,18280,18281,18282,18283,18284,18285,18286,
-18287,18288,18289,18290,18291,18292,18293,18294,18295,18296,18297,18298,
-18299,18300,18301,18302,18303,18304,18305,18306,18307,18308,18309,18310,
-18311,18312,18313,18314,18315,18316,18317,18318,18319,18320,18321,18322,
-18323,18324,18325,18326,18327,18328,18329,18330,18331,18332,18333,18334,
-18335,18336,18337,18338,18339,18340,18341,18342,18343,18344,18345,18346,
-18347,18348,18349,18350,18351,18352,18353,18354,18355,18356,18357,18358,
-18359,18360,18361,18362,18363,18364,18365,18366,18367,18368,18369,18370,
-18371,18372,18373,18374,18375,18376,18377,18378,18379,18380,18381,18382,
-18383,18384,18385,18386,18387,18388,18389,18390,18391,18392,18393,18394,
-18395,18396,18397,18398,18399,18400,18401,18402,18403,18404,18405,18406,
-18407,18408,18409,18410,18411,18412,18413,18414,18415,18416,18417,18418,
-18419,18420,18421,18422,18423,18424,18425,18426,18427,18428,18429,18430,
-18431,18432,18433,18434,18435,18436,18437,18438,18439,18440,18441,18442,
-18443,18444,18445,18446,18447,18448,18449,18450,18451,18452,18453,18454,
-18455,18456,18457,18458,18459,18460,18461,18462,18463,18464,18465,18466,
-18467,18468,18469,18470,18471,18472,18473,18474,18475,18476,18477,18478,
-18479,18480,18481,18482,18483,18484,18485,18486,18487,18488,18489,18490,
-18491,18492,18493,18494,18495,18496,18497,18498,18499,18500,18501,18502,
-18503,18504,18505,18506,18507,18508,18509,18510,18511,18512,18513,18514,
-18515,18516,18517,18518,18519,18520,18521,18522,18523,18524,18525,18526,
-18527,18528,18529,18530,18531,18532,18533,18534,18535,18536,18537,18538,
-18539,18540,18541,18542,18543,18544,18545,18546,18547,18548,18549,18550,
-18551,18552,18553,18554,18555,18556,18557,18558,18559,18560,18561,18562,
-18563,18564,18565,18566,18567,18568,18569,18570,18571,18572,18573,18574,
-18575,18576,18577,18578,18579,18580,18581,18582,18583,18584,18585,18586,
-18587,18588,18589,18590,18591,18592,18593,18594,18595,18596,18597,18598,
-18599,18600,18601,18602,18603,18604,18605,18606,18607,18608,18609,18610,
-18611,18612,18613,18614,18615,18616,18617,18618,18619,18620,18621,18622,
-18623,18624,18625,18626,18627,18628,18629,18630,18631,18632,18633,18634,
-18635,18636,18637,18638,18639,18640,18641,18642,18643,18644,18645,18646,
-18647,18648,18649,18650,18651,18652,18653,18654,18655,18656,18657,18658,
-18659,18660,18661,18662,18663,18664,18665,18666,18667,18668,18669,18670,
-18671,18672,18673,18674,18675,18676,18677,18678,18679,18680,18681,18682,
-18683,18684,18685,18686,18687,18688,18689,18690,18691,18692,18693,18694,
-18695,18696,18697,18698,18699,18700,18701,18702,18703,18704,18705,18706,
-18707,18708,18709,18710,18711,18712,18713,18714,18715,18716,18717,18718,
-18719,18720,18721,18722,18723,18724,18725,18726,18727,18728,18729,18730,
-18731,18732,18733,18734,18735,18736,18737,18738,18739,18740,18741,18742,
-18743,18744,18745,18746,18747,18748,18749,18750,18751,18752,18753,18754,
-18755,18756,18757,18758,18759,18760,18761,18762,18763,18764,18765,18766,
-18767,18768,18769,18770,18771,18772,18773,18774,18775,18776,18777,18778,
-18779,18780,18781,18782,18783,18784,18785,18786,18787,18788,18789,18790,
-18791,18792,18793,18794,18795,18796,18797,18798,18799,18800,18801,18802,
-18803,18804,18805,18806,18807,18808,18809,18810,18811,18812,18813,18814,
-18815,18816,18817,18818,18819,18820,18821,18822,18823,18824,18825,18826,
-18827,18828,18829,18830,18831,18832,18833,18834,18835,18836,18837,18838,
-18839,18840,18841,18842,18843,18844,18845,18846,18847,18848,18849,18850,
-18851,18852,18853,18854,18855,18856,18857,18858,18859,18860,18861,18862,
-18863,18864,18865,18866,18867,18868,18869,18870,18871,18872,18873,18874,
-18875,18876,18877,18878,18879,18880,18881,18882,18883,18884,18885,18886,
-18887,18888,18889,18890,18891,18892,18893,18894,18895,18896,18897,18898,
-18899,18900,18901,18902,18903,18904,18905,18906,18907,18908,18909,18910,
-18911,18912,18913,18914,18915,18916,18917,18918,18919,18920,18921,18922,
-18923,18924,18925,18926,18927,18928,18929,18930,18931,18932,18933,18934,
-18935,18936,18937,18938,18939,18940,18941,18942,18943,18944,18945,18946,
-18947,18948,18949,18950,18951,18952,18953,18954,18955,18956,18957,18958,
-18959,18960,18961,18962,18963,18964,18965,18966,18967,18968,18969,18970,
-18971,18972,18973,18974,18975,18976,18977,18978,18979,18980,18981,18982,
-18983,18984,18985,18986,18987,18988,18989,18990,18991,18992,18993,18994,
-18995,18996,18997,18998,18999,19000,19001,19002,19003,19004,19005,19006,
-19007,19008,19009,19010,19011,19012,19013,19014,19015,19016,19017,19018,
-19019,19020,19021,19022,19023,19024,19025,19026,19027,19028,19029,19030,
-19031,19032,19033,19034,19035,19036,19037,19038,19039,19040,19041,19042,
-19043,19044,19045,19046,19047,19048,19049,19050,19051,19052,19053,19054,
-19055,19056,19057,19058,19059,19060,19061,19062,19063,19064,19065,19066,
-19067,19068,19069,19070,19071,19072,19073,19074,19075,19076,19077,19078,
-19079,19080,19081,19082,19083,19084,19085,19086,19087,19088,19089,19090,
-19091,19092,19093,19094,19095,19096,19097,19098,19099,19100,19101,19102,
-19103,19104,19105,19106,19107,19108,19109,19110,19111,19112,19113,19114,
-19115,19116,19117,19118,19119,19120,19121,19122,19123,19124,19125,19126,
-19127,19128,19129,19130,19131,19132,19133,19134,19135,19136,19137,19138,
-19139,19140,19141,19142,19143,19144,19145,19146,19147,19148,19149,19150,
-19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161,19162,
-19163,19164,19165,19166,19167,19168,19169,19170,19171,19172,19173,19174,
-19175,19176,19177,19178,19179,19180,19181,19182,19183,19184,19185,19186,
-19187,19188,19189,19190,19191,19192,19193,19194,19195,19196,19197,19198,
-19199,19200,19201,19202,19203,19204,19205,19206,19207,19208,19209,19210,
-19211,19212,19213,19214,19215,19216,19217,19218,19219,19220,19221,19222,
-19223,19224,19225,19226,19227,19228,19229,19230,19231,19232,19233,19234,
-19235,19236,19237,19238,19239,19240,19241,19242,19243,19244,19245,19246,
-19247,19248,19249,19250,19251,19252,19253,19254,19255,19256,19257,19258,
-19259,19260,19261,19262,19263,19264,19265,19266,19267,19268,19269,19270,
-19271,19272,19273,19274,19275,19276,19277,19278,19279,19280,19281,19282,
-19283,19284,19285,19286,19287,19288,19289,19290,19291,19292,19293,19294,
-19295,19296,19297,19298,19299,19300,19301,19302,19303,19304,19305,19306,
-19307,19308,19309,19310,19311,19312,19313,19314,19315,19316,19317,19318,
-19319,19320,19321,19322,19323,19324,19325,19326,19327,19328,19329,19330,
-19331,19332,19333,19334,19335,19336,19337,19338,19339,19340,19341,19342,
-19343,19344,19345,19346,19347,19348,19349,19350,19351,19352,19353,19354,
-19355,19356,19357,19358,19359,19360,19361,19362,19363,19364,19365,19366,
-19367,19368,19369,19370,19371,19372,19373,19374,19375,19376,19377,19378,
-19379,19380,19381,19382,19383,19384,19385,19386,19387,19388,19389,19390,
-19391,19392,19393,19394,19395,19396,19397,19398,19399,19400,19401,19402,
-19403,19404,19405,19406,19407,19408,19409,19410,19411,19412,19413,19414,
-19415,19416,19417,19418,19419,19420,19421,19422,19423,19424,19425,19426,
-19427,19428,19429,19430,19431,19432,19433,19434,19435,19436,19437,19438,
-19439,19440,19441,19442,19443,19444,19445,19446,19447,19448,19449,19450,
-19451,19452,19453,19454,19455,19456,19457,19458,19459,19460,19461,19462,
-19463,19464,19465,19466,19467,19468,19469,19470,19471,19472,19473,19474,
-19475,19476,19477,19478,19479,19480,19481,19482,19483,19484,19485,19486,
-19487,19488,19489,19490,19491,19492,19493,19494,19495,19496,19497,19498,
-19499,19500,19501,19502,19503,19504,19505,19506,19507,19508,19509,19510,
-19511,19512,19513,19514,19515,19516,19517,19518,19519,19520,19521,19522,
-19523,19524,19525,19526,19527,19528,19529,19530,19531,19532,19533,19534,
-19535,19536,19537,19538,19539,19540,19541,19542,19543,19544,19545,19546,
-19547,19548,19549,19550,19551,19552,19553,19554,19555,19556,19557,19558,
-19559,19560,19561,19562,19563,19564,19565,19566,19567,19568,19569,19570,
-19571,19572,19573,19574,19575,19576,19577,19578,19579,19580,19581,19582,
-19583,19584,19585,19586,19587,19588,19589,19590,19591,19592,19593,19594,
-19595,19596,19597,19598,19599,19600,19601,19602,19603,19604,19605,19606,
-19607,19608,19609,19610,19611,19612,19613,19614,19615,19616,19617,19618,
-19619,19620,19621,19622,19623,19624,19625,19626,19627,19628,19629,19630,
-19631,19632,19633,19634,19635,19636,19637,19638,19639,19640,19641,19642,
-19643,19644,19645,19646,19647,19648,19649,19650,19651,19652,19653,19654,
-19655,19656,19657,19658,19659,19660,19661,19662,19663,19664,19665,19666,
-19667,19668,19669,19670,19671,19672,19673,19674,19675,19676,19677,19678,
-19679,19680,19681,19682,19683,19684,19685,19686,19687,19688,19689,19690,
-19691,19692,19693,19694,19695,19696,19697,19698,19699,19700,19701,19702,
-19703,19704,19705,19706,19707,19708,19709,19710,19711,19712,19713,19714,
-19715,19716,19717,19718,19719,19720,19721,19722,19723,19724,19725,19726,
-19727,19728,19729,19730,19731,19732,19733,19734,19735,19736,19737,19738,
-19739,19740,19741,19742,19743,19744,19745,19746,19747,19748,19749,19750,
-19751,19752,19753,19754,19755,19756,19757,19758,19759,19760,19761,19762,
-19763,19764,19765,19766,19767,19768,19769,19770,19771,19772,19773,19774,
-19775,19776,19777,19778,19779,19780,19781,19782,19783,19784,19785,19786,
-19787,19788,19789,19790,19791,19792,19793,19794,19795,19796,19797,19798,
-19799,19800,19801,19802,19803,19804,19805,19806,19807,19808,19809,19810,
-19811,19812,19813,19814,19815,19816,19817,19818,19819,19820,19821,19822,
-19823,19824,19825,19826,19827,19828,19829,19830,19831,19832,19833,19834,
-19835,19836,19837,19838,19839,19840,19841,19842,19843,19844,19845,19846,
-19847,19848,19849,19850,19851,19852,19853,19854,19855,19856,19857,19858,
-19859,19860,19861,19862,19863,19864,19865,19866,19867,19868,19869,19870,
-19871,19872,19873,19874,19875,19876,19877,19878,19879,19880,19881,19882,
-19883,19884,19885,19886,19887,19888,19889,19890,19891,19892,19893,19894,
-19895,19896,19897,19898,19899,19900,19901,19902,19903,19904,19905,19906,
-19907,19908,19909,19910,19911,19912,19913,19914,19915,19916,19917,19918,
-19919,19920,19921,19922,19923,19924,19925,19926,19927,19928,19929,19930,
-19931,19932,19933,19934,19935,19936,19937,19938,19939,19940,19941,19942,
-19943,19944,19945,19946,19947,19948,19949,19950,19951,19952,19953,19954,
-19955,19956,19957,19958,19959,19960,19961,19962,19963,19964,19965,19966,
-19967,19968,19969,19970,19971,19972,19973,19974,19975,19976,19977,19978,
-19979,19980,19981,19982,19983,19984,19985,19986,19987,19988,19989,19990,
-19991,19992,19993,19994,19995,19996,19997,19998,19999,20000,20001,20002,
-20003,20004,20005,20006,20007,20008,20009,20010,20011,20012,20013,20014,
-20015,20016,20017,20018,20019,20020,20021,20022,20023,20024,20025,20026,
-20027,20028,20029,20030,20031,20032,20033,20034,20035,20036,20037,20038,
-20039,20040,20041,20042,20043,20044,20045,20046,20047,20048,20049,20050,
-20051,20052,20053,20054,20055,20056,20057,20058,20059,20060,20061,20062,
-20063,20064,20065,20066,20067,20068,20069,20070,20071,20072,20073,20074,
-20075,20076,20077,20078,20079,20080,20081,20082,20083,20084,20085,20086,
-20087,20088,20089,20090,20091,20092,20093,20094,20095,20096,20097,20098,
-20099,20100,20101,20102,20103,20104,20105,20106,20107,20108,20109,20110,
-20111,20112,20113,20114,20115,20116,20117,20118,20119,20120,20121,20122,
-20123,20124,20125,20126,20127,20128,20129,20130,20131,20132,20133,20134,
-20135,20136,20137,20138,20139,20140,20141,20142,20143,20144,20145,20146,
-20147,20148,20149,20150,20151,20152,20153,20154,20155,20156,20157,20158,
-20159,20160,20161,20162,20163,20164,20165,20166,20167,20168,20169,20170,
-20171,20172,20173,20174,20175,20176,20177,20178,20179,20180,20181,20182,
-20183,20184,20185,20186,20187,20188,20189,20190,20191,20192,20193,20194,
-20195,20196,20197,20198,20199,20200,20201,20202,20203,20204,20205,20206,
-20207,20208,20209,20210,20211,20212,20213,20214,20215,20216,20217,20218,
-20219,20220,20221,20222,20223,20224,20225,20226,20227,20228,20229,20230,
-20231,20232,20233,20234,20235,20236,20237,20238,20239,20240,20241,20242,
-20243,20244,20245,20246,20247,20248,20249,20250,20251,20252,20253,20254,
-20255,20256,20257,20258,20259,20260,20261,20262,20263,20264,20265,20266,
-20267,20268,20269,20270,20271,20272,20273,20274,20275,20276,20277,20278,
-20279,20280,20281,20282,20283,20284,20285,20286,20287,20288,20289,20290,
-20291,20292,20293,20294,20295,20296,20297,20298,20299,20300,20301,20302,
-20303,20304,20305,20306,20307,20308,20309,20310,20311,20312,20313,20314,
-20315,20316,20317,20318,20319,20320,20321,20322,20323,20324,20325,20326,
-20327,20328,20329,20330,20331,20332,20333,20334,20335,20336,20337,20338,
-20339,20340,20341,20342,20343,20344,20345,20346,20347,20348,20349,20350,
-20351,20352,20353,20354,20355,20356,20357,20358,20359,20360,20361,20362,
-20363,20364,20365,20366,20367,20368,20369,20370,20371,20372,20373,20374,
-20375,20376,20377,20378,20379,20380,20381,20382,20383,20384,20385,20386,
-20387,20388,20389,20390,20391,20392,20393,20394,20395,20396,20397,20398,
-20399,20400,20401,20402,20403,20404,20405,20406,20407,20408,20409,20410,
-20411,20412,20413,20414,20415,20416,20417,20418,20419,20420,20421,20422,
-20423,20424,20425,20426,20427,20428,20429,20430,20431,20432,20433,20434,
-20435,20436,20437,20438,20439,20440,20441,20442,20443,20444,20445,20446,
-20447,20448,20449,20450,20451,20452,20453,20454,20455,20456,20457,20458,
-20459,20460,20461,20462,20463,20464,20465,20466,20467,20468,20469,20470,
-20471,20472,20473,20474,20475,20476,20477,20478,20479,20480,20481,20482,
-20483,20484,20485,20486,20487,20488,20489,20490,20491,20492,20493,20494,
-20495,20496,20497,20498,20499,20500,20501,20502,20503,20504,20505,20506,
-20507,20508,20509,20510,20511,20512,20513,20514,20515,20516,20517,20518,
-20519,20520,20521,20522,20523,20524,20525,20526,20527,20528,20529,20530,
-20531,20532,20533,20534,20535,20536,20537,20538,20539,20540,20541,20542,
-20543,20544,20545,20546,20547,20548,20549,20550,20551,20552,20553,20554,
-20555,20556,20557,20558,20559,20560,20561,20562,20563,20564,20565,20566,
-20567,20568,20569,20570,20571,20572,20573,20574,20575,20576,20577,20578,
-20579,20580,20581,20582,20583,20584,20585,20586,20587,20588,20589,20590,
-20591,20592,20593,20594,20595,20596,20597,20598,20599,20600,20601,20602,
-20603,20604,20605,20606,20607,20608,20609,20610,20611,20612,20613,20614,
-20615,20616,20617,20618,20619,20620,20621,20622,20623,20624,20625,20626,
-20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,
-20639,20640,20641,20642,20643,20644,20645,20646,20647,20648,20649,20650,
-20651,20652,20653,20654,20655,20656,20657,20658,20659,20660,20661,20662,
-20663,20664,20665,20666,20667,20668,20669,20670,20671,20672,20673,20674,
-20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,
-20687,20688,20689,20690,20691,20692,20693,20694,20695,20696,20697,20698,
-20699,20700,20701,20702,20703,20704,20705,20706,20707,20708,20709,20710,
-20711,20712,20713,20714,20715,20716,20717,20718,20719,20720,20721,20722,
-20723,20724,20725,20726,20727,20728,20729,20730,20731,20732,20733,20734,
-20735,20736,20737,20738,20739,20740,20741,20742,20743,20744,20745,20746,
-20747,20748,20749,20750,20751,20752,20753,20754,20755,20756,20757,20758,
-20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20769,20770,
-20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,
-20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,
-20795,20796,20797,20798,20799,20800,20801,20802,20803,20804,20805,20806,
-20807,20808,20809,20810,20811,20812,20813,20814,20815,20816,20817,20818,
-20819,20820,20821,20822,20823,20824,20825,20826,20827,20828,20829,20830,
-20831,20832,20833,20834,20835,20836,20837,20838,20839,20840,20841,20842,
-20843,20844,20845,20846,20847,20848,20849,20850,20851,20852,20853,20854,
-20855,20856,20857,20858,20859,20860,20861,20862,20863,20864,20865,20866,
-20867,20868,20869,20870,20871,20872,20873,20874,20875,20876,20877,20878,
-20879,20880,20881,20882,20883,20884,20885,20886,20887,20888,20889,20890,
-20891,20892,20893,20894,20895,20896,20897,20898,20899,20900,20901,20902,
-20903,20904,20905,20906,20907,20908,20909,20910,20911,20912,20913,20914,
-20915,20916,20917,20918,20919,20920,20921,20922,20923,20924,20925,20926,
-20927,20928,20929,20930,20931,20932,20933,20934,20935,20936,20937,20938,
-20939,20940,20941,20942,20943,20944,20945,20946,20947,20948,20949,20950,
-20951,20952,20953,20954,20955,20956,20957,20958,20959,20960,20961,20962,
-20963,20964,20965,20966,20967,20968,20969,20970,20971,20972,20973,20974,
-20975,20976,20977,20978,20979,20980,20981,20982,20983,20984,20985,20986,
-20987,20988,20989,20990,20991,20992,20993,20994,20995,20996,20997,20998,
-20999,21000,21001,21002,21003,21004,21005,21006,21007,21008,21009,21010,
-21011,21012,21013,21014,21015,21016,21017,21018,21019,21020,21021,21022,
-21023,21024,21025,21026,21027,21028,21029,21030,21031,21032,21033,21034,
-21035,21036,21037,21038,21039,21040,21041,21042,21043,21044,21045,21046,
-21047,21048,21049,21050,21051,21052,21053,21054,21055,21056,21057,21058,
-21059,21060,21061,21062,21063,21064,21065,21066,21067,21068,21069,21070,
-21071,21072,21073,21074,21075,21076,21077,21078,21079,21080,21081,21082,
-21083,21084,21085,21086,21087,21088,21089,21090,21091,21092,21093,21094,
-21095,21096,21097,21098,21099,21100,21101,21102,21103,21104,21105,21106,
-21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21117,21118,
-21119,21120,21121,21122,21123,21124,21125,21126,21127,21128,21129,21130,
-21131,21132,21133,21134,21135,21136,21137,21138,21139,21140,21141,21142,
-21143,21144,21145,21146,21147,21148,21149,21150,21151,21152,21153,21154,
-21155,21156,21157,21158,21159,21160,21161,21162,21163,21164,21165,21166,
-21167,21168,21169,21170,21171,21172,21173,21174,21175,21176,21177,21178,
-21179,21180,21181,21182,21183,21184,21185,21186,21187,21188,21189,21190,
-21191,21192,21193,21194,21195,21196,21197,21198,21199,21200,21201,21202,
-21203,21204,21205,21206,21207,21208,21209,21210,21211,21212,21213,21214,
-21215,21216,21217,21218,21219,21220,21221,21222,21223,21224,21225,21226,
-21227,21228,21229,21230,21231,21232,21233,21234,21235,21236,21237,21238,
-21239,21240,21241,21242,21243,21244,21245,21246,21247,21248,21249,21250,
-21251,21252,21253,21254,21255,21256,21257,21258,21259,21260,21261,21262,
-21263,21264,21265,21266,21267,21268,21269,21270,21271,21272,21273,21274,
-21275,21276,21277,21278,21279,21280,21281,21282,21283,21284,21285,21286,
-21287,21288,21289,21290,21291,21292,21293,21294,21295,21296,21297,21298,
-21299,21300,21301,21302,21303,21304,21305,21306,21307,21308,21309,21310,
-21311,21312,21313,21314,21315,21316,21317,21318,21319,21320,21321,21322,
-21323,21324,21325,21326,21327,21328,21329,21330,21331,21332,21333,21334,
-21335,21336,21337,21338,21339,21340,21341,21342,21343,21344,21345,21346,
-21347,21348,21349,21350,21351,21352,21353,21354,21355,21356,21357,21358,
-21359,21360,21361,21362,21363,21364,21365,21366,21367,21368,21369,21370,
-21371,21372,21373,21374,21375,21376,21377,21378,21379,21380,21381,21382,
-21383,21384,21385,21386,21387,21388,21389,21390,21391,21392,21393,21394,
-21395,21396,21397,21398,21399,21400,21401,21402,21403,21404,21405,21406,
-21407,21408,21409,21410,21411,21412,21413,21414,21415,21416,21417,21418,
-21419,21420,21421,21422,21423,21424,21425,21426,21427,21428,21429,21430,
-21431,21432,21433,21434,21435,21436,21437,21438,21439,21440,21441,21442,
-21443,21444,21445,21446,21447,21448,21449,21450,21451,21452,21453,21454,
-21455,21456,21457,21458,21459,21460,21461,21462,21463,21464,21465,21466,
-21467,21468,21469,21470,21471,21472,21473,21474,21475,21476,21477,21478,
-21479,21480,21481,21482,21483,21484,21485,21486,21487,21488,21489,21490,
-21491,21492,21493,21494,21495,21496,21497,21498,21499,21500,21501,21502,
-21503,21504,21505,21506,21507,21508,21509,21510,21511,21512,21513,21514,
-21515,21516,21517,21518,21519,21520,21521,21522,21523,21524,21525,21526,
-21527,21528,21529,21530,21531,21532,21533,21534,21535,21536,21537,21538,
-21539,21540,21541,21542,21543,21544,21545,21546,21547,21548,21549,21550,
-21551,21552,21553,21554,21555,21556,21557,21558,21559,21560,21561,21562,
-21563,21564,21565,21566,21567,21568,21569,21570,21571,21572,21573,21574,
-21575,21576,21577,21578,21579,21580,21581,21582,21583,21584,21585,21586,
-21587,21588,21589,21590,21591,21592,21593,21594,21595,21596,21597,21598,
-21599,21600,21601,21602,21603,21604,21605,21606,21607,21608,21609,21610,
-21611,21612,21613,21614,21615,21616,21617,21618,21619,21620,21621,21622,
-21623,21624,21625,21626,21627,21628,21629,21630,21631,21632,21633,21634,
-21635,21636,21637,21638,21639,21640,21641,21642,21643,21644,21645,21646,
-21647,21648,21649,21650,21651,21652,21653,21654,21655,21656,21657,21658,
-21659,21660,21661,21662,21663,21664,21665,21666,21667,21668,21669,21670,
-21671,21672,21673,21674,21675,21676,21677,21678,21679,21680,21681,21682,
-21683,21684,21685,21686,21687,21688,21689,21690,21691,21692,21693,21694,
-21695,21696,21697,21698,21699,21700,21701,21702,21703,21704,21705,21706,
-21707,21708,21709,21710,21711,21712,21713,21714,21715,21716,21717,21718,
-21719,21720,21721,21722,21723,21724,21725,21726,21727,21728,21729,21730,
-21731,21732,21733,21734,21735,21736,21737,21738,21739,21740,21741,21742,
-21743,21744,21745,21746,21747,21748,21749,21750,21751,21752,21753,21754,
-21755,21756,21757,21758,21759,21760,21761,21762,21763,21764,21765,21766,
-21767,21768,21769,21770,21771,21772,21773,21774,21775,21776,21777,21778,
-21779,21780,21781,21782,21783,21784,21785,21786,21787,21788,21789,21790,
-21791,21792,21793,21794,21795,21796,21797,21798,21799,21800,21801,21802,
-21803,21804,21805,21806,21807,21808,21809,21810,21811,21812,21813,21814,
-21815,21816,21817,21818,21819,21820,21821,21822,21823,21824,21825,21826,
-21827,21828,21829,21830,21831,21832,21833,21834,21835,21836,21837,21838,
-21839,21840,21841,21842,21843,21844,21845,21846,21847,21848,21849,21850,
-21851,21852,21853,21854,21855,21856,21857,21858,21859,21860,21861,21862,
-21863,21864,21865,21866,21867,21868,21869,21870,21871,21872,21873,21874,
-21875,21876,21877,21878,21879,21880,21881,21882,21883,21884,21885,21886,
-21887,21888,21889,21890,21891,21892,21893,21894,21895,21896,21897,21898,
-21899,21900,21901,21902,21903,21904,21905,21906,21907,21908,21909,21910,
-21911,21912,21913,21914,21915,21916,21917,21918,21919,21920,21921,21922,
-21923,21924,21925,21926,21927,21928,21929,21930,21931,21932,21933,21934,
-21935,21936,21937,21938,21939,21940,21941,21942,21943,21944,21945,21946,
-21947,21948,21949,21950,21951,21952,21953,21954,21955,21956,21957,21958,
-21959,21960,21961,21962,21963,21964,21965,21966,21967,21968,21969,21970,
-21971,21972,21973,21974,21975,21976,21977,21978,21979,21980,21981,21982,
-21983,21984,21985,21986,21987,21988,21989,21990,21991,21992,21993,21994,
-21995,21996,21997,21998,21999,22000,22001,22002,22003,22004,22005,22006,
-22007,22008,22009,22010,22011,22012,22013,22014,22015,22016,22017,22018,
-22019,22020,22021,22022,22023,22024,22025,22026,22027,22028,22029,22030,
-22031,22032,22033,22034,22035,22036,22037,22038,22039,22040,22041,22042,
-22043,22044,22045,22046,22047,22048,22049,22050,22051,22052,22053,22054,
-22055,22056,22057,22058,22059,22060,22061,22062,22063,22064,22065,22066,
-22067,22068,22069,22070,22071,22072,22073,22074,22075,22076,22077,22078,
-22079,22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,
-22091,22092,22093,22094,22095,22096,22097,22098,22099,22100,22101,22102,
-22103,22104,22105,22106,22107,22108,22109,22110,22111,22112,22113,22114,
-22115,22116,22117,22118,22119,22120,22121,22122,22123,22124,22125,22126,
-22127,22128,22129,22130,22131,22132,22133,22134,22135,22136,22137,22138,
-22139,22140,22141,22142,22143,22144,22145,22146,22147,22148,22149,22150,
-22151,22152,22153,22154,22155,22156,22157,22158,22159,22160,22161,22162,
-22163,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,
-22175,22176,22177,22178,22179,22180,22181,22182,22183,22184,22185,22186,
-22187,22188,22189,22190,22191,22192,22193,22194,22195,22196,22197,22198,
-22199,22200,22201,22202,22203,22204,22205,22206,22207,22208,22209,22210,
-22211,22212,22213,22214,22215,22216,22217,22218,22219,22220,22221,22222,
-22223,22224,22225,22226,22227,22228,22229,22230,22231,22232,22233,22234,
-22235,22236,22237,22238,22239,22240,22241,22242,22243,22244,22245,22246,
-22247,22248,22249,22250,22251,22252,22253,22254,22255,22256,22257,22258,
-22259,22260,22261,22262,22263,22264,22265,22266,22267,22268,22269,22270,
-22271,22272,22273,22274,22275,22276,22277,22278,22279,22280,22281,22282,
-22283,22284,22285,22286,22287,22288,22289,22290,22291,22292,22293,22294,
-22295,22296,22297,22298,22299,22300,22301,22302,22303,22304,22305,22306,
-22307,22308,22309,22310,22311,22312,22313,22314,22315,22316,22317,22318,
-22319,22320,22321,22322,22323,22324,22325,22326,22327,22328,22329,22330,
-22331,22332,22333,22334,22335,22336,22337,22338,22339,22340,22341,22342,
-22343,22344,22345,22346,22347,22348,22349,22350,22351,22352,22353,22354,
-22355,22356,22357,22358,22359,22360,22361,22362,22363,22364,22365,22366,
-22367,22368,22369,22370,22371,22372,22373,22374,22375,22376,22377,22378,
-22379,22380,22381,22382,22383,22384,22385,22386,22387,22388,22389,22390,
-22391,22392,22393,22394,22395,22396,22397,22398,22399,22400,22401,22402,
-22403,22404,22405,22406,22407,22408,22409,22410,22411,22412,22413,22414,
-22415,22416,22417,22418,22419,22420,22421,22422,22423,22424,22425,22426,
-22427,22428,22429,22430,22431,22432,22433,22434,22435,22436,22437,22438,
-22439,22440,22441,22442,22443,22444,22445,22446,22447,22448,22449,22450,
-22451,22452,22453,22454,22455,22456,22457,22458,22459,22460,22461,22462,
-22463,22464,22465,22466,22467,22468,22469,22470,22471,22472,22473,22474,
-22475,22476,22477,22478,22479,22480,22481,22482,22483,22484,22485,22486,
-22487,22488,22489,22490,22491,22492,22493,22494,22495,22496,22497,22498,
-22499,22500,22501,22502,22503,22504,22505,22506,22507,22508,22509,22510,
-22511,22512,22513,22514,22515,22516,22517,22518,22519,22520,22521,22522,
-22523,22524,22525,22526,22527,22528,22529,22530,22531,22532,22533,22534,
-22535,22536,22537,22538,22539,22540,22541,22542,22543,22544,22545,22546,
-22547,22548,22549,22550,22551,22552,22553,22554,22555,22556,22557,22558,
-22559,22560,22561,22562,22563,22564,22565,22566,22567,22568,22569,22570,
-22571,22572,22573,22574,22575,22576,22577,22578,22579,22580,22581,22582,
-22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,
-22595,22596,22597,22598,22599,22600,22601,22602,22603,22604,22605,22606,
-22607,22608,22609,22610,22611,22612,22613,22614,22615,22616,22617,22618,
-22619,22620,22621,22622,22623,22624,22625,22626,22627,22628,22629,22630,
-22631,22632,22633,22634,22635,22636,22637,22638,22639,22640,22641,22642,
-22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,22654,
-22655,22656,22657,22658,22659,22660,22661,22662,22663,22664,22665,22666,
-22667,22668,22669,22670,22671,22672,22673,22674,22675,22676,22677,22678,
-22679,22680,22681,22682,22683,22684,22685,22686,22687,22688,22689,22690,
-22691,22692,22693,22694,22695,22696,22697,22698,22699,22700,22701,22702,
-22703,22704,22705,22706,22707,22708,22709,22710,22711,22712,22713,22714,
-22715,22716,22717,22718,22719,22720,22721,22722,22723,22724,22725,22726,
-22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22737,22738,
-22739,22740,22741,22742,22743,22744,22745,22746,22747,22748,22749,22750,
-22751,22752,22753,22754,22755,22756,22757,22758,22759,22760,22761,22762,
-22763,22764,22765,22766,22767,22768,22769,22770,22771,22772,22773,22774,
-22775,22776,22777,22778,22779,22780,22781,22782,22783,22784,22785,22786,
-22787,22788,22789,22790,22791,22792,22793,22794,22795,22796,22797,22798,
-22799,22800,22801,22802,22803,22804,22805,22806,22807,22808,22809,22810,
-22811,22812,22813,22814,22815,22816,22817,22818,22819,22820,22821,22822,
-22823,22824,22825,22826,22827,22828,22829,22830,22831,22832,22833,22834,
-22835,22836,22837,22838,22839,22840,22841,22842,22843,22844,22845,22846,
-22847,22848,22849,22850,22851,22852,22853,22854,22855,22856,22857,22858,
-22859,22860,22861,22862,22863,22864,22865,22866,22867,22868,22869,22870,
-22871,22872,22873,22874,22875,22876,22877,22878,22879,22880,22881,22882,
-22883,22884,22885,22886,22887,22888,22889,22890,22891,22892,22893,22894,
-22895,22896,22897,22898,22899,22900,22901,22902,22903,22904,22905,22906,
-22907,22908,22909,22910,22911,22912,22913,22914,22915,22916,22917,22918,
-22919,22920,22921,22922,22923,22924,22925,22926,22927,22928,22929,22930,
-22931,22932,22933,22934,22935,22936,22937,22938,22939,22940,22941,22942,
-22943,22944,22945,22946,22947,22948,22949,22950,22951,22952,22953,22954,
-22955,22956,22957,22958,22959,22960,22961,22962,22963,22964,22965,22966,
-22967,22968,22969,22970,22971,22972,22973,22974,22975,22976,22977,22978,
-22979,22980,22981,22982,22983,22984,22985,22986,22987,22988,22989,22990,
-22991,22992,22993,22994,22995,22996,22997,22998,22999,23000,23001,23002,
-23003,23004,23005,23006,23007,23008,23009,23010,23011,23012,23013,23014,
-23015,23016,23017,23018,23019,23020,23021,23022,23023,23024,23025,23026,
-23027,23028,23029,23030,23031,23032,23033,23034,23035,23036,23037,23038,
-23039,23040,23041,23042,23043,23044,23045,23046,23047,23048,23049,23050,
-23051,23052,23053,23054,23055,23056,23057,23058,23059,23060,23061,23062,
-23063,23064,23065,23066,23067,23068,23069,23070,23071,23072,23073,23074,
-23075,23076,23077,23078,23079,23080,23081,23082,23083,23084,23085,23086,
-23087,23088,23089,23090,23091,23092,23093,23094,23095,23096,23097,23098,
-23099,23100,23101,23102,23103,23104,23105,23106,23107,23108,23109,23110,
-23111,23112,23113,23114,23115,23116,23117,23118,23119,23120,23121,23122,
-23123,23124,23125,23126,23127,23128,23129,23130,23131,23132,23133,23134,
-23135,23136,23137,23138,23139,23140,23141,23142,23143,23144,23145,23146,
-23147,23148,23149,23150,23151,23152,23153,23154,23155,23156,23157,23158,
-23159,23160,23161,23162,23163,23164,23165,23166,23167,23168,23169,23170,
-23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,
-23183,23184,23185,23186,23187,23188,23189,23190,23191,23192,23193,23194,
-23195,23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,
-23207,23208,23209,23210,23211,23212,23213,23214,23215,23216,23217,23218,
-23219,23220,23221,23222,23223,23224,23225,23226,23227,23228,23229,23230,
-23231,23232,23233,23234,23235,23236,23237,23238,23239,23240,23241,23242,
-23243,23244,23245,23246,23247,23248,23249,23250,23251,23252,23253,23254,
-23255,23256,23257,23258,23259,23260,23261,23262,23263,23264,23265,23266,
-23267,23268,23269,23270,23271,23272,23273,23274,23275,23276,23277,23278,
-23279,23280,23281,23282,23283,23284,23285,23286,23287,23288,23289,23290,
-23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,23301,23302,
-23303,23304,23305,23306,23307,23308,23309,23310,23311,23312,23313,23314,
-23315,23316,23317,23318,23319,23320,23321,23322,23323,23324,23325,23326,
-23327,23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,
-23339,23340,23341,23342,23343,23344,23345,23346,23347,23348,23349,23350,
-23351,23352,23353,23354,23355,23356,23357,23358,23359,23360,23361,23362,
-23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,
-23375,23376,23377,23378,23379,23380,23381,23382,23383,23384,23385,23386,
-23387,23388,23389,23390,23391,23392,23393,23394,23395,23396,23397,23398,
-23399,23400,23401,23402,23403,23404,23405,23406,23407,23408,23409,23410,
-23411,23412,23413,23414,23415,23416,23417,23418,23419,23420,23421,23422,
-23423,23424,23425,23426,23427,23428,23429,23430,23431,23432,23433,23434,
-23435,23436,23437,23438,23439,23440,23441,23442,23443,23444,23445,23446,
-23447,23448,23449,23450,23451,23452,23453,23454,23455,23456,23457,23458,
-23459,23460,23461,23462,23463,23464,23465,23466,23467,23468,23469,23470,
-23471,23472,23473,23474,23475,23476,23477,23478,23479,23480,23481,23482,
-23483,23484,23485,23486,23487,23488,23489,23490,23491,23492,23493,23494,
-23495,23496,23497,23498,23499,23500,23501,23502,23503,23504,23505,23506,
-23507,23508,23509,23510,23511,23512,23513,23514,23515,23516,23517,23518,
-23519,23520,23521,23522,23523,23524,23525,23526,23527,23528,23529,23530,
-23531,23532,23533,23534,23535,23536,23537,23538,23539,23540,23541,23542,
-23543,23544,23545,23546,23547,23548,23549,23550,23551,23552,23553,23554,
-23555,23556,23557,23558,23559,23560,23561,23562,23563,23564,23565,23566,
-23567,23568,23569,23570,23571,23572,23573,23574,23575,23576,23577,23578,
-23579,23580,23581,23582,23583,23584,23585,23586,23587,23588,23589,23590,
-23591,23592,23593,23594,23595,23596,23597,23598,23599,23600,23601,23602,
-23603,23604,23605,23606,23607,23608,23609,23610,23611,23612,23613,23614,
-23615,23616,23617,23618,23619,23620,23621,23622,23623,23624,23625,23626,
-23627,23628,23629,23630,23631,23632,23633,23634,23635,23636,23637,23638,
-23639,23640,23641,23642,23643,23644,23645,23646,23647,23648,23649,23650,
-23651,23652,23653,23654,23655,23656,23657,23658,23659,23660,23661,23662,
-23663,23664,23665,23666,23667,23668,23669,23670,23671,23672,23673,23674,
-23675,23676,23677,23678,23679,23680,23681,23682,23683,23684,23685,23686,
-23687,23688,23689,23690,23691,23692,23693,23694,23695,23696,23697,23698,
-23699,23700,23701,23702,23703,23704,23705,23706,23707,23708,23709,23710,
-23711,23712,23713,23714,23715,23716,23717,23718,23719,23720,23721,23722,
-23723,23724,23725,23726,23727,23728,23729,23730,23731,23732,23733,23734,
-23735,23736,23737,23738,23739,23740,23741,23742,23743,23744,23745,23746,
-23747,23748,23749,23750,23751,23752,23753,23754,23755,23756,23757,23758,
-23759,23760,23761,23762,23763,23764,23765,23766,23767,23768,23769,23770,
-23771,23772,23773,23774,23775,23776,23777,23778,23779,23780,23781,23782,
-23783,23784,23785,23786,23787,23788,23789,23790,23791,23792,23793,23794,
-23795,23796,23797,23798,23799,23800,23801,23802,23803,23804,23805,23806,
-23807,23808,23809,23810,23811,23812,23813,23814,23815,23816,23817,23818,
-23819,23820,23821,23822,23823,23824,23825,23826,23827,23828,23829,23830,
-23831,23832,23833,23834,23835,23836,23837,23838,23839,23840,23841,23842,
-23843,23844,23845,23846,23847,23848,23849,23850,23851,23852,23853,23854,
-23855,23856,23857,23858,23859,23860,23861,23862,23863,23864,23865,23866,
-23867,23868,23869,23870,23871,23872,23873,23874,23875,23876,23877,23878,
-23879,23880,23881,23882,23883,23884,23885,23886,23887,23888,23889,23890,
-23891,23892,23893,23894,23895,23896,23897,23898,23899,23900,23901,23902,
-23903,23904,23905,23906,23907,23908,23909,23910,23911,23912,23913,23914,
-23915,23916,23917,23918,23919,23920,23921,23922,23923,23924,23925,23926,
-23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23938,
-23939,23940,23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,
-23951,23952,23953,23954,23955,23956,23957,23958,23959,23960,23961,23962,
-23963,23964,23965,23966,23967,23968,23969,23970,23971,23972,23973,23974,
-23975,23976,23977,23978,23979,23980,23981,23982,23983,23984,23985,23986,
-23987,23988,23989,23990,23991,23992,23993,23994,23995,23996,23997,23998,
-23999,24000,24001,24002,24003,24004,24005,24006,24007,24008,24009,24010,
-24011,24012,24013,24014,24015,24016,24017,24018,24019,24020,24021,24022,
-24023,24024,24025,24026,24027,24028,24029,24030,24031,24032,24033,24034,
-24035,24036,24037,24038,24039,24040,24041,24042,24043,24044,24045,24046,
-24047,24048,24049,24050,24051,24052,24053,24054,24055,24056,24057,24058,
-24059,24060,24061,24062,24063,24064,24065,24066,24067,24068,24069,24070,
-24071,24072,24073,24074,24075,24076,24077,24078,24079,24080,24081,24082,
-24083,24084,24085,24086,24087,24088,24089,24090,24091,24092,24093,24094,
-24095,24096,24097,24098,24099,24100,24101,24102,24103,24104,24105,24106,
-24107,24108,24109,24110,24111,24112,24113,24114,24115,24116,24117,24118,
-24119,24120,24121,24122,24123,24124,24125,24126,24127,24128,24129,24130,
-24131,24132,24133,24134,24135,24136,24137,24138,24139,24140,24141,24142,
-24143,24144,24145,24146,24147,24148,24149,24150,24151,24152,24153,24154,
-24155,24156,24157,24158,24159,24160,24161,24162,24163,24164,24165,24166,
-24167,24168,24169,24170,24171,24172,24173,24174,24175,24176,24177,24178,
-24179,24180,24181,24182,24183,24184,24185,24186,24187,24188,24189,24190,
-24191,24192,24193,24194,24195,24196,24197,24198,24199,24200,24201,24202,
-24203,24204,24205,24206,24207,24208,24209,24210,24211,24212,24213,24214,
-24215,24216,24217,24218,24219,24220,24221,24222,24223,24224,24225,24226,
-24227,24228,24229,24230,24231,24232,24233,24234,24235,24236,24237,24238,
-24239,24240,24241,24242,24243,24244,24245,24246,24247,24248,24249,24250,
-24251,24252,24253,24254,24255,24256,24257,24258,24259,24260,24261,24262,
-24263,24264,24265,24266,24267,24268,24269,24270,24271,24272,24273,24274,
-24275,24276,24277,24278,24279,24280,24281,24282,24283,24284,24285,24286,
-24287,24288,24289,24290,24291,24292,24293,24294,24295,24296,24297,24298,
-24299,24300,24301,24302,24303,24304,24305,24306,24307,24308,24309,24310,
-24311,24312,24313,24314,24315,24316,24317,24318,24319,24320,24321,24322,
-24323,24324,24325,24326,24327,24328,24329,24330,24331,24332,24333,24334,
-24335,24336,24337,24338,24339,24340,24341,24342,24343,24344,24345,24346,
-24347,24348,24349,24350,24351,24352,24353,24354,24355,24356,24357,24358,
-24359,24360,24361,24362,24363,24364,24365,24366,24367,24368,24369,24370,
-24371,24372,24373,24374,24375,24376,24377,24378,24379,24380,24381,24382,
-24383,24384,24385,24386,24387,24388,24389,24390,24391,24392,24393,24394,
-24395,24396,24397,24398,24399,24400,24401,24402,24403,24404,24405,24406,
-24407,24408,24409,24410,24411,24412,24413,24414,24415,24416,24417,24418,
-24419,24420,24421,24422,24423,24424,24425,24426,24427,24428,24429,24430,
-24431,24432,24433,24434,24435,24436,24437,24438,24439,24440,24441,24442,
-24443,24444,24445,24446,24447,24448,24449,24450,24451,24452,24453,24454,
-24455,24456,24457,24458,24459,24460,24461,24462,24463,24464,24465,24466,
-24467,24468,24469,24470,24471,24472,24473,24474,24475,24476,24477,24478,
-24479,24480,24481,24482,24483,24484,24485,24486,24487,24488,24489,24490,
-24491,24492,24493,24494,24495,24496,24497,24498,24499,24500,24501,24502,
-24503,24504,24505,24506,24507,24508,24509,24510,24511,24512,24513,24514,
-24515,24516,24517,24518,24519,24520,24521,24522,24523,24524,24525,24526,
-24527,24528,24529,24530,24531,24532,24533,24534,24535,24536,24537,24538,
-24539,24540,24541,24542,24543,24544,24545,24546,24547,24548,24549,24550,
-24551,24552,24553,24554,24555,24556,24557,24558,24559,24560,24561,24562,
-24563,24564,24565,24566,24567,24568,24569,24570,24571,24572,24573,24574,
-24575,24576,24577,24578,24579,24580,24581,24582,24583,24584,24585,24586,
-24587,24588,24589,24590,24591,24592,24593,24594,24595,24596,24597,24598,
-24599,24600,24601,24602,24603,24604,24605,24606,24607,24608,24609,24610,
-24611,24612,24613,24614,24615,24616,24617,24618,24619,24620,24621,24622,
-24623,24624,24625,24626,24627,24628,24629,24630,24631,24632,24633,24634,
-24635,24636,24637,24638,24639,24640,24641,24642,24643,24644,24645,24646,
-24647,24648,24649,24650,24651,24652,24653,24654,24655,24656,24657,24658,
-24659,24660,24661,24662,24663,24664,24665,24666,24667,24668,24669,24670,
-24671,24672,24673,24674,24675,24676,24677,24678,24679,24680,24681,24682,
-24683,24684,24685,24686,24687,24688,24689,24690,24691,24692,24693,24694,
-24695,24696,24697,24698,24699,24700,24701,24702,24703,24704,24705,24706,
-24707,24708,24709,24710,24711,24712,24713,24714,24715,24716,24717,24718,
-24719,24720,24721,24722,24723,24724,24725,24726,24727,24728,24729,24730,
-24731,24732,24733,24734,24735,24736,24737,24738,24739,24740,24741,24742,
-24743,24744,24745,24746,24747,24748,24749,24750,24751,24752,24753,24754,
-24755,24756,24757,24758,24759,24760,24761,24762,24763,24764,24765,24766,
-24767,24768,24769,24770,24771,24772,24773,24774,24775,24776,24777,24778,
-24779,24780,24781,24782,24783,24784,24785,24786,24787,24788,24789,24790,
-24791,24792,24793,24794,24795,24796,24797,24798,24799,24800,24801,24802,
-24803,24804,24805,24806,24807,24808,24809,24810,24811,24812,24813,24814,
-24815,24816,24817,24818,24819,24820,24821,24822,24823,24824,24825,24826,
-24827,24828,24829,24830,24831,24832,24833,24834,24835,24836,24837,24838,
-24839,24840,24841,24842,24843,24844,24845,24846,24847,24848,24849,24850,
-24851,24852,24853,24854,24855,24856,24857,24858,24859,24860,24861,24862,
-24863,24864,24865,24866,24867,24868,24869,24870,24871,24872,24873,24874,
-24875,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,
-24887,24888,24889,24890,24891,24892,24893,24894,24895,24896,24897,24898,
-24899,24900,24901,24902,24903,24904,24905,24906,24907,24908,24909,24910,
-24911,24912,24913,24914,24915,24916,24917,24918,24919,24920,24921,24922,
-24923,24924,24925,24926,24927,24928,24929,24930,24931,24932,24933,24934,
-24935,24936,24937,24938,24939,24940,24941,24942,24943,24944,24945,24946,
-24947,24948,24949,24950,24951,24952,24953,24954,24955,24956,24957,24958,
-24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,
-24971,24972,24973,24974,24975,24976,24977,24978,24979,24980,24981,24982,
-24983,24984,24985,24986,24987,24988,24989,24990,24991,24992,24993,24994,
-24995,24996,24997,24998,24999,25000,25001,25002,25003,25004,25005,25006,
-25007,25008,25009,25010,25011,25012,25013,25014,25015,25016,25017,25018,
-25019,25020,25021,25022,25023,25024,25025,25026,25027,25028,25029,25030,
-25031,25032,25033,25034,25035,25036,25037,25038,25039,25040,25041,25042,
-25043,25044,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,
-25055,25056,25057,25058,25059,25060,25061,25062,25063,25064,25065,25066,
-25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25077,25078,
-25079,25080,25081,25082,25083,25084,25085,25086,25087,25088,25089,25090,
-25091,25092,25093,25094,25095,25096,25097,25098,25099,25100,25101,25102,
-25103,25104,25105,25106,25107,25108,25109,25110,25111,25112,25113,25114,
-25115,25116,25117,25118,25119,25120,25121,25122,25123,25124,25125,25126,
-25127,25128,25129,25130,25131,25132,25133,25134,25135,25136,25137,25138,
-25139,25140,25141,25142,25143,25144,25145,25146,25147,25148,25149,25150,
-25151,25152,25153,25154,25155,25156,25157,25158,25159,25160,25161,25162,
-25163,25164,25165,25166,25167,25168,25169,25170,25171,25172,25173,25174,
-25175,25176,25177,25178,25179,25180,25181,25182,25183,25184,25185,25186,
-25187,25188,25189,25190,25191,25192,25193,25194,25195,25196,25197,25198,
-25199,25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,
-25211,25212,25213,25214,25215,25216,25217,25218,25219,25220,25221,25222,
-25223,25224,25225,25226,25227,25228,25229,25230,25231,25232,25233,25234,
-25235,25236,25237,25238,25239,25240,25241,25242,25243,25244,25245,25246,
-25247,25248,25249,25250,25251,25252,25253,25254,25255,25256,25257,25258,
-25259,25260,25261,25262,25263,25264,25265,25266,25267,25268,25269,25270,
-25271,25272,25273,25274,25275,25276,25277,25278,25279,25280,25281,25282,
-25283,25284,25285,25286,25287,25288,25289,25290,25291,25292,25293,25294,
-25295,25296,25297,25298,25299,25300,25301,25302,25303,25304,25305,25306,
-25307,25308,25309,25310,25311,25312,25313,25314,25315,25316,25317,25318,
-25319,25320,25321,25322,25323,25324,25325,25326,25327,25328,25329,25330,
-25331,25332,25333,25334,25335,25336,25337,25338,25339,25340,25341,25342,
-25343,25344,25345,25346,25347,25348,25349,25350,25351,25352,25353,25354,
-25355,25356,25357,25358,25359,25360,25361,25362,25363,25364,25365,25366,
-25367,25368,25369,25370,25371,25372,25373,25374,25375,25376,25377,25378,
-25379,25380,25381,25382,25383,25384,25385,25386,25387,25388,25389,25390,
-25391,25392,25393,25394,25395,25396,25397,25398,25399,25400,25401,25402,
-25403,25404,25405,25406,25407,25408,25409,25410,25411,25412,25413,25414,
-25415,25416,25417,25418,25419,25420,25421,25422,25423,25424,25425,25426,
-25427,25428,25429,25430,25431,25432,25433,25434,25435,25436,25437,25438,
-25439,25440,25441,25442,25443,25444,25445,25446,25447,25448,25449,25450,
-25451,25452,25453,25454,25455,25456,25457,25458,25459,25460,25461,25462,
-25463,25464,25465,25466,25467,25468,25469,25470,25471,25472,25473,25474,
-25475,25476,25477,25478,25479,25480,25481,25482,25483,25484,25485,25486,
-25487,25488,25489,25490,25491,25492,25493,25494,25495,25496,25497,25498,
-25499,25500,25501,25502,25503,25504,25505,25506,25507,25508,25509,25510,
-25511,25512,25513,25514,25515,25516,25517,25518,25519,25520,25521,25522,
-25523,25524,25525,25526,25527,25528,25529,25530,25531,25532,25533,25534,
-25535,25536,25537,25538,25539,25540,25541,25542,25543,25544,25545,25546,
-25547,25548,25549,25550,25551,25552,25553,25554,25555,25556,25557,25558,
-25559,25560,25561,25562,25563,25564,25565,25566,25567,25568,25569,25570,
-25571,25572,25573,25574,25575,25576,25577,25578,25579,25580,25581,25582,
-25583,25584,25585,25586,25587,25588,25589,25590,25591,25592,25593,25594,
-25595,25596,25597,25598,25599,25600,25601,25602,25603,25604,25605,25606,
-25607,25608,25609,25610,25611,25612,25613,25614,25615,25616,25617,25618,
-25619,25620,25621,25622,25623,25624,25625,25626,25627,25628,25629,25630,
-25631,25632,25633,25634,25635,25636,25637,25638,25639,25640,25641,25642,
-25643,25644,25645,25646,25647,25648,25649,25650,25651,25652,25653,25654,
-25655,25656,25657,25658,25659,25660,25661,25662,25663,25664,25665,25666,
-25667,25668,25669,25670,25671,25672,25673,25674,25675,25676,25677,25678,
-25679,25680,25681,25682,25683,25684,25685,25686,25687,25688,25689,25690,
-25691,25692,25693,25694,25695,25696,25697,25698,25699,25700,25701,25702,
-25703,25704,25705,25706,25707,25708,25709,25710,25711,25712,25713,25714,
-25715,25716,25717,25718,25719,25720,25721,25722,25723,25724,25725,25726,
-25727,25728,25729,25730,25731,25732,25733,25734,25735,25736,25737,25738,
-25739,25740,25741,25742,25743,25744,25745,25746,25747,25748,25749,25750,
-25751,25752,25753,25754,25755,25756,25757,25758,25759,25760,25761,25762,
-25763,25764,25765,25766,25767,25768,25769,25770,25771,25772,25773,25774,
-25775,25776,25777,25778,25779,25780,25781,25782,25783,25784,25785,25786,
-25787,25788,25789,25790,25791,25792,25793,25794,25795,25796,25797,25798,
-25799,25800,25801,25802,25803,25804,25805,25806,25807,25808,25809,25810,
-25811,25812,25813,25814,25815,25816,25817,25818,25819,25820,25821,25822,
-25823,25824,25825,25826,25827,25828,25829,25830,25831,25832,25833,25834,
-25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,
-25847,25848,25849,25850,25851,25852,25853,25854,25855,25856,25857,25858,
-25859,25860,25861,25862,25863,25864,25865,25866,25867,25868,25869,25870,
-25871,25872,25873,25874,25875,25876,25877,25878,25879,25880,25881,25882,
-25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25893,25894,
-25895,25896,25897,25898,25899,25900,25901,25902,25903,25904,25905,25906,
-25907,25908,25909,25910,25911,25912,25913,25914,25915,25916,25917,25918,
-25919,25920,25921,25922,25923,25924,25925,25926,25927,25928,25929,25930,
-25931,25932,25933,25934,25935,25936,25937,25938,25939,25940,25941,25942,
-25943,25944,25945,25946,25947,25948,25949,25950,25951,25952,25953,25954,
-25955,25956,25957,25958,25959,25960,25961,25962,25963,25964,25965,25966,
-25967,25968,25969,25970,25971,25972,25973,25974,25975,25976,25977,25978,
-25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,
-25991,25992,25993,25994,25995,25996,25997,25998,25999,26000,26001,26002,
-26003,26004,26005,26006,26007,26008,26009,26010,26011,26012,26013,26014,
-26015,26016,26017,26018,26019,26020,26021,26022,26023,26024,26025,26026,
-26027,26028,26029,26030,26031,26032,26033,26034,26035,26036,26037,26038,
-26039,26040,26041,26042,26043,26044,26045,26046,26047,26048,26049,26050,
-26051,26052,26053,26054,26055,26056,26057,26058,26059,26060,26061,26062,
-26063,26064,26065,26066,26067,26068,26069,26070,26071,26072,26073,26074,
-26075,26076,26077,26078,26079,26080,26081,26082,26083,26084,26085,26086,
-26087,26088,26089,26090,26091,26092,26093,26094,26095,26096,26097,26098,
-26099,26100,26101,26102,26103,26104,26105,26106,26107,26108,26109,26110,
-26111,26112,26113,26114,26115,26116,26117,26118,26119,26120,26121,26122,
-26123,26124,26125,26126,26127,26128,26129,26130,26131,26132,26133,26134,
-26135,26136,26137,26138,26139,26140,26141,26142,26143,26144,26145,26146,
-26147,26148,26149,26150,26151,26152,26153,26154,26155,26156,26157,26158,
-26159,26160,26161,26162,26163,26164,26165,26166,26167,26168,26169,26170,
-26171,26172,26173,26174,26175,26176,26177,26178,26179,26180,26181,26182,
-26183,26184,26185,26186,26187,26188,26189,26190,26191,26192,26193,26194,
-26195,26196,26197,26198,26199,26200,26201,26202,26203,26204,26205,26206,
-26207,26208,26209,26210,26211,26212,26213,26214,26215,26216,26217,26218,
-26219,26220,26221,26222,26223,26224,26225,26226,26227,26228,26229,26230,
-26231,26232,26233,26234,26235,26236,26237,26238,26239,26240,26241,26242,
-26243,26244,26245,26246,26247,26248,26249,26250,26251,26252,26253,26254,
-26255,26256,26257,26258,26259,26260,26261,26262,26263,26264,26265,26266,
-26267,26268,26269,2