Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/d68406e9c9b317ed461ea...
...commit
http://git.netsurf-browser.org/netsurf.git/commit/d68406e9c9b317ed461ea9b...
...tree
http://git.netsurf-browser.org/netsurf.git/tree/d68406e9c9b317ed461ea9b0a...
The branch, tlsa/shared-styles has been updated
discards 5a9ff3d64529a496a23304aa6b12fbfada1bd481 (commit)
discards dab351ee9f37fca6caa6fb983190e333516c6576 (commit)
discards 55979bbd697e3c8e32bbd1b39bc1b9bd88da3af4 (commit)
discards 1a6bea150e98773e1b895259b88d00638a0b4868 (commit)
discards 3008ebc170ff94193649a67eddd962922438a2fa (commit)
via d68406e9c9b317ed461ea9b0ad4af20268ba238d (commit)
via 2a8ce59c0e5b74449f8d9a1dc535c966fb3352d8 (commit)
via f6750060c39eb36e888e293d1fe6ed0b7e5a7cbc (commit)
via 73c7cdc5fadcda7a562fbf34bf84e394c59e7534 (commit)
via e612366e1f50be4559349a3bc754fc875b5af330 (commit)
via e5a2538b6dcb6404d4404ebb4403e0c58e8ce9b1 (commit)
via 401cc36924585ce8292212c73dc8aab372056620 (commit)
via 4d1ef3bac4ba09423a51af809ef0c9220402f050 (commit)
via 727bbbd216ccd0f4c11164b54348a120f5311d40 (commit)
via 125f131714b0cd800b1cbe17633ffa71b051c368 (commit)
via 50393c9fc6893624aa1b4726a3534f1c222e43d3 (commit)
via 896c71abbe62a0fe94978a8a6cbcc30529170c0b (commit)
via 5c719d540eeddbb6eca352e242d748c5b289e6b8 (commit)
via 2f27852229d1aaa0bc1db0093e4b4218a97da976 (commit)
via 718f17a57f592a524bfba4e0fb3053db799024e1 (commit)
via 0397a6637d53907b2c5720a7dd71f6db7741a061 (commit)
via 5e4011bee724326e5a2d779b50b72b27e18d9054 (commit)
via c3b7e650c5efb8262bc0998babaf9947ad29797a (commit)
via b54174e54a7f55cb6e11b6fb20f6615b37f5b65a (commit)
via a7324d39a46a561535dcb26fac3fbd8f593dbf94 (commit)
via ed5fd918438ca3f564a5e27f363eddc1439dd58e (commit)
via 336326af3aab93f31474fa6de28782457ae4a1c0 (commit)
via e3a5fcf816e8b3b9c1488b0f9029b1f757f8ab7f (commit)
via 1284731d1a98ab7c62f15d95f575f9a20010b002 (commit)
via c2d51384c13db930bb43819a4ad4709153a3e871 (commit)
via 6eb62081592c997b937c0131f041b291d421aae1 (commit)
via bfe3e6abbc547a542122fa34545df697ca36d684 (commit)
via ee5efa1349a20f3a0ae2500abff0cc15a00732ef (commit)
via f65ea4b096fbb2a555547a400224108bfdb955df (commit)
via 0247bed13f43ef7b940845074f32f9ba928cdb83 (commit)
via 39d967e94b4715fa5d43c5e1fcbcc95ad31f7562 (commit)
via 47794b32ffe736f95cdf5e6edb6da0478cb0584b (commit)
via 7a6f0c765aa01dbf7dfc21766bd17ee94d88786f (commit)
via 43f29e43115665d6b919f38aaae4c6bfa731d71e (commit)
via 576488f14c46a0d6ccd72175e4cf68c162eb2fd3 (commit)
via 469147b5936857930015d26111f4e6fdb25a5941 (commit)
via c22706b9049c4c85205a8cc9a3dc72a4e4a52be5 (commit)
via 3aacba15f821f8d7902473cff93bc506bad3b547 (commit)
via 60c52e1eaf54ffa0cc6981d458c683c403609727 (commit)
via 310162474a3690e00244a0edd87361bf1352be82 (commit)
via 4ca737408cc8c1777a01e362883886c230ee19dc (commit)
via b1d477219d7270298de11a9089462f7a0d3cd051 (commit)
via 00eb6a8e8878724b7ff44c3e502dc1b74e1309cf (commit)
via 5a107a466bb3153d0d6aea01f4574a907a921ed8 (commit)
via 71f296a41ce7509ebbf052c80cf0cdaaf6ce0451 (commit)
via 519775a65cbe3609b1f3795465365801aaa671ac (commit)
via f2e56834be6ee3ac5246cbe6a835793d60fbe6d3 (commit)
via b1533a7f768c58dbc3f62246b64ce1329f53269c (commit)
via 67cbdf6befb0be2285b367bcd66e0b5f61c9fa55 (commit)
via 25cd49034cb8133223e44dfc763c8d736f2135ba (commit)
via 78067fc29a89452a08a10d6b907f81e4ce77fbb9 (commit)
via 396b445599731cceb7173bdc2336ccc1e59871a7 (commit)
via 0fabb20cc59ee16441e037867675093200f4b378 (commit)
via 218839d05a60f5077f0c33ad5df6b25288a49b7a (commit)
via 9198e80c2465e7c34bddc0387003f5debd63ef51 (commit)
via d795f1ca2dbc8c13acfd613f5c6af1d09cecec12 (commit)
via 6098646e727533f7e7a7c062822e51a59c34161e (commit)
via 8ff9abf5b69c2040ff70890ac85d459a9c9e5537 (commit)
via 8c04742e39ec8587ea019bdfe42ee8a3449c523e (commit)
via 78daba6f3c033e3769fb4fef8fb0cf1d62c08828 (commit)
via d7924a5849aa8977ef261956353fbf4795454408 (commit)
via 3a67d34f696e8d2c804336e54cf026c05ad8858c (commit)
via b07f4db57932be5883f60877b8820137ece733f0 (commit)
via 36bf691ceea67bb0938e6fbdd2802423c53cc6a9 (commit)
via 0423704eb1a5930d63a5c75add26ccb5e9eb1ff2 (commit)
via 4458b96ff289c3d85d89574e0678f665809b2ba7 (commit)
via 1bb7d295bb6c59c0a21b0eedf69f939ebd2a7ed9 (commit)
via dc0729150c2fd4ed4ad594ea5240d69d8ab65a3c (commit)
via 37c715c5224b5e86925e6b0b9270c95dd45d4b19 (commit)
via ef202aeef57d8766ea368d3148c550a97c604ae7 (commit)
via aabea8eceb8d77cef934e7b4d0cd2015f1103411 (commit)
via 27adf07fb7752ede0d3a5f874d7c85f2e71c47c2 (commit)
via 65b510fbc3ad822ab8c75e6d94eaee5b6ceb07a4 (commit)
via 5206518a75d34cdf03a5118276e7ba4c106b6bfc (commit)
via ac8eccd035a4676938fb08d70b23bc4dfb9fa4d6 (commit)
via 53141c70899962fbcf88e56d08a7ecd8d5e15f9c (commit)
via dd38897a26cf888d2c546b7db9da8ec125a37b53 (commit)
via 920cb0571d93f956385e193389dd1f564efc5304 (commit)
via 6afda499c290bea17fe2bcf5fcd257a1770528cf (commit)
via 5f5ca2c20587e035278163c9b444b36cfff6dced (commit)
via c752c85618a57f8c82dc2e939ba2bf735e6c8372 (commit)
via 2f52338328e694e3ba1141424cbf3f413bcfbaf9 (commit)
via 79068dd50f8617186822d871e292c726e7f85658 (commit)
via 629287c224ad87a2fc813009ce9fcd46f46baff8 (commit)
via 0ddb60d82acfa0b8bc967562d4a3672fd3780d20 (commit)
via 0645bc7570974531be344544b68a7e93908d1796 (commit)
via 37ea372a100f6a1a47afc47ce9430ed6e2b4c44b (commit)
via 6d0d964cac44ede2b6defa4d9330f51d22b30689 (commit)
via eb17f4ab37cd47a12f97f0ab37b92d5297bd6743 (commit)
via 9409bc2ad7d71916accae0cf855ac068cb6a4bb3 (commit)
via 9666888f0c76b5bb690022a9a125417554f7d0b0 (commit)
via c7ca9ae8198c9b42ebf8d13491f14e63d692e147 (commit)
via f624e9f27269a5ecd37f3ed49e45e37b95894420 (commit)
via 3e6feede1f59536e5bee9e448da1de3bea53af29 (commit)
via 0805bf2cd63bc1bc5c7c55b651562c745276a8d7 (commit)
via 0d4105907d5843c06f8b545adebe4d7d45ad1afd (commit)
via 47fb74ee8805c68c8849e57014e6094eb55b527d (commit)
via 3bcc9922ee240b288205d475e6e6a2f6bc6ec718 (commit)
via d676b64bec6e714ec6220289b12c5b0c7c7c0c5c (commit)
via c1937ee617e1238ca74efa664e25843d8fc2785f (commit)
via 4f843d3b6f09fe6639498504263515fbd6ea3c5f (commit)
via 02fb81009ea365f98ac6861a109a809a1bffc42a (commit)
via b516854d0a3e8d658c65d18176f8b44f9af8c48e (commit)
via 2b71eef7637e95617f7c5bd880e41106c989fdfe (commit)
via 079667ee6cad0c2f2d97a3a5435c70edc72ff78e (commit)
via 2f129cdef75cb85db44487d9e86fb4de3dab5023 (commit)
via b667375dcc0c03d7bb33d578c1340e5cba8417bb (commit)
via 94a740c7c1881ef6bc883a68c42a34714ddf79b5 (commit)
via d57dec24548d7d8b58c54d0647b6d1339a09cb88 (commit)
via 5fdf040e90c9adebc6ecc4ffe7c0ac0734853863 (commit)
via 4fa47860350521d27d25ab5723ee26d596936f2b (commit)
via 71849b0c04919c51a5907deefb8e71aa154fb12c (commit)
via 444721354ee84639bbbd7c864ea256840dc4518a (commit)
via 2f68549812e5b70f6f51283c35c91bfd576c6ed3 (commit)
via e1769827fcfd58ae044bf9822df081dbfc306154 (commit)
via b54bf459a50636a36bff578ed3a7a763ef097295 (commit)
via 450cefbd490c2e11262ee15d025ffb18b0e9ff16 (commit)
via c39096c30d26f425df78958597dda8e720777e30 (commit)
via 5263712ad4950fb1ec12ed9516c5b6fd198ec66f (commit)
via d01cecdf7f341aeb4920437c0e644059c4b7090b (commit)
via cb178413efc7d8c6cbc595884e88c5b9d82898a4 (commit)
via d97958a9732edce338dcb77f6ed698e429afe038 (commit)
via a182bb55011e786c133c4db20b3de4acbb053593 (commit)
via 5546a3dbcdc052a68fc4f4b8ad7d6e30a851b50e (commit)
via af66ed31944cdb74e2ad4a75a4fffe97535260ed (commit)
via 15777ee7503db5a8499ff7c8423415ef1d13a1a5 (commit)
via 0e606ac64b28cde3985fed15e29bfdfdb3070192 (commit)
via 2071c2a91b5f8647d95ffc95e524657bff8089d9 (commit)
via 46ff49baef23b4fff4eda0925793880b3d0eeaf5 (commit)
via 15256411d8e9227832e012d49658a651e3d62e3e (commit)
via 7b6d89db04ca01f7770e713fc4977e6f55dbf6c6 (commit)
via f3e0267ccdbc02b8a9295042c0256956b10d95c7 (commit)
via b8ea788aba7605233b25f14a48da1662b630e035 (commit)
via ce321410577f384e19042ea20b30ed6cbb00eda2 (commit)
via 3877d4ad03134c727624b85e830539b3fe15dbdf (commit)
via 967cfda0f86d5fcc67f5d57b6c1b7bb6ae6489df (commit)
via 0d4942d42c7b96a5b8c672d0c7075fda534f1262 (commit)
via 9443f201feab3b5db858f9f4990480983812006f (commit)
via 0636ee0f209af1bbc080c87058c7e1f8191e8b15 (commit)
via 9f925da516cdd8a566e4d57d6f80f9614b852774 (commit)
via 5a569322a49c86fc39b3d7a854f929881f6cd29c (commit)
via c7275edc26880cb097fd086b96d4ce09fff6551b (commit)
via 7c4fa72fa4f66588459f32b9427d610b0078c142 (commit)
via f075b4cde6e39fccce442e235ea2d1f7852f3a49 (commit)
via b72f7507484c235989c78f42ed6644d7a92ad673 (commit)
via f34a223b9a1fb04f67c67edbe81f38b8adf9f73c (commit)
via a897d87d18c9b35bd520a44fa5a76521fb0ccf15 (commit)
via b9a23939b29d5973a04a9172248a98be4b6a8ef1 (commit)
via 6fd2c320f23e267416438de9425be777c81bec5f (commit)
via b5f1c5eee20c2bb0f48098151d15f4f36fa9de67 (commit)
via 315339cbc801c35b2c53418b6b55705bbdef62ca (commit)
via d0371d5d3b34f0a7b4b8a2d6ef59f938260faf3a (commit)
via b7eb35ef24a1b7ea9484bb1d67e7b198abbc117b (commit)
via a46d9057d87d9850afb726e01f12ff9d819ba9fb (commit)
via 6a4a7d7c254bf509bb392bf97abd8eb89c95ace5 (commit)
via fbc3f36fb5a72c2cc399d5e83291ffabc299017e (commit)
via 9ebdc7dd7abb7537f9e47a5dd8dab8585696da0b (commit)
via 33264e012b6153e3da12eb3582c4561d6f238d2f (commit)
via 4bdd4cf7b604b140ed203d30b5730879de92bdd6 (commit)
via 51c2dd70e2bb8da61f683916111f083ec0263953 (commit)
via 46945f636221ccf0751f3f0e2e78c6e6d33cab7f (commit)
via 63dba3a0618a2116ec395937b04f65740fe529f3 (commit)
via 73c6476112181bd5e151be719dde7d5cd48e14c3 (commit)
via 410f6fdb9ef5e12506dd50ae6dc74ebc4a06dae4 (commit)
via 1a43dd21b38805424d717c68a95635d4386bd6d8 (commit)
via 1f07c457401a6d944c26319571beb32f3b9009f5 (commit)
via d137bda4547ec6ecc07dec4c32097428f022ed7c (commit)
via e5c34567dcb6a8693f67163bb46f32fa2acc4811 (commit)
via d1ccd3e53d45071b9c715aaacf9d60e261701957 (commit)
via de75959362f83adee9f7b879fe5e76701575af7c (commit)
via 1e83301251beed8fd0450a2a0d71d8a9451ccc46 (commit)
via 1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93 (commit)
via 5b880e586c9358db0ae86bb95edb2559f16d5da4 (commit)
via eb366fa0d8cebc235e77f0279b9bc955af3ee1bc (commit)
via 6a002558551b5dd57c062268079aef7a63f444e7 (commit)
via 63227a214bb8e0f576ecb684313e5f3a3bdcf96f (commit)
via 00aa1e2d3501ee0a004415a56a845db51c660ef4 (commit)
via 46f3670fae57fb1b05a1d8304f500b0ac3350b16 (commit)
via 7ea2488d1c2ca066f3c48de0ef874a5dfeb368b4 (commit)
via 12bef8a0d94984dd99250f0c04677833d4302203 (commit)
via da5638debc89f510bfd2f018bb81563f097b9de3 (commit)
via a15e5a7869e8c14b0c4351eef168b88285cc05b4 (commit)
via 41f219192c6a9ee34a14d0cb149946eff9eeec50 (commit)
via cdaae7b30e22373b99117438a15e062e8749688d (commit)
via 944248ce3205881df9268d2c3f9f0cb52fc2f075 (commit)
via 52d182e71e3098148b98e7ae24b7740305960634 (commit)
via 2e4bfc5dc3ae3d6c13fbc6f956b611354ed37257 (commit)
via 61342f4dee1c74bce4096cc5a886231f829388ff (commit)
via fdb9a42eff665d848e443386740da8e5dcdf74b1 (commit)
via e0198789ae1dcadbb8423478d165de60077517dc (commit)
via 06221c23407df35c31a32309a8ef8b13b12cb417 (commit)
via a73d53845cc332de3ac09a2348a917b956e48f6a (commit)
via 33eb8d3324dee7dfaacd98d08aa559884531a24b (commit)
via 257666499deef1e6ff03c9167c282a5aead8fc6f (commit)
via 914ba332e2853baa30809eda11a878ab686253f6 (commit)
via 4bbf2ac58af4a660d108ec51867a7cf8e674cc39 (commit)
via cba6bdb481545e404e0769b051090b16046a99f5 (commit)
via fea40a0a78a70a29573bbdc940ea6f9ccdb6093b (commit)
via aaf7ebf9fd28d7e895f7fd8559970f2d0f9a0a7d (commit)
via 0c42364b6758bef734c5032688c2ee1e5c460118 (commit)
via 528fce72627493a302febc521417992f25e570f8 (commit)
via 9b222fdeb66d149628aace66853ee29627dfabc1 (commit)
via 69a133969bf0aaaa64a928403ade8f1dc88a7ae0 (commit)
via a2edd98c19db5eb880d51bcc55c2fc32f0cc2035 (commit)
via 87ebe668804b2e480c691b16e699ebc242ff3f3a (commit)
via b429a89ed64ce38ae6ea8136e24bfa80e1f837dc (commit)
via f9bb4ba71dde3586b0f77d7c4cd82fbcf6be1129 (commit)
via 9c2fbde9173fec32e60e69b5d6f8e0041d6e28f6 (commit)
via 7c14bff469c9d1bd027555b3fb7a820853f0a02e (commit)
via a28be122703cb0331d4b9c56ea38f233703e8ccb (commit)
via 527a13a841869c62cacd0cf5db2ba4d5402018c9 (commit)
via b19cd801fdf4c9c27000df53250b022c624127f4 (commit)
via 0c2f4667863d3579947b7c73b43bec61f9d9140d (commit)
via c759b2a2626eb4daea9156dccf8ed2412458888f (commit)
via c43d09af64e578187ce18e2c882d24179d83662c (commit)
via 45171214edd2741e00206df93799a649dcc71384 (commit)
via c2dd23462619cba285c904a91024024a55c16b69 (commit)
via 477506b7a1349e47938789a78dd4626250e672d8 (commit)
via beb5b9a542f94794db212fd78ff13387740517d6 (commit)
via ff1de8997694e3278e8d72ced1adb866983443fc (commit)
via d90ab621f8021c5680a4702dbc20cbf94ce3ee3b (commit)
via fd9aa16ece1af9af828c4606bbd9df975e5d2e3d (commit)
via f0c14aab7d88d3d011ec1a5c153e78760590fb8f (commit)
via a7fb19f3a90372ddd84911e793413d9ceb244a07 (commit)
via 1088c4cd38cdc314712d2ee428389872a5450c2b (commit)
via 31d45274b6b15f4d89575904a04429715c9b117e (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 (5a9ff3d64529a496a23304aa6b12fbfada1bd481)
\
N -- N -- N (d68406e9c9b317ed461ea9b0ad4af20268ba238d)
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=d68406e9c9b317ed461...
commit d68406e9c9b317ed461ea9b0ad4af20268ba238d
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Update to use libcss API which allows interned partial styles.
diff --git a/css/select.c b/css/select.c
index c9e5f7e..a4225cb 100644
--- a/css/select.c
+++ b/css/select.c
@@ -252,6 +252,7 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
uint64_t media, const css_stylesheet *inline_style)
{
+ css_computed_style *composed;
css_select_results *styles;
int pseudo_element;
css_error error;
@@ -273,11 +274,16 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node
*n,
error = css_computed_style_compose(ctx->parent_style,
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
nscss_compute_font_size, NULL,
- &(styles->styles[CSS_PSEUDO_ELEMENT_NONE]));
+ &composed);
if (error != CSS_OK) {
css_select_results_destroy(styles);
return NULL;
}
+
+ /* Replace select_results style with composed style */
+ css_computed_style_destroy(
+ styles->styles[CSS_PSEUDO_ELEMENT_NONE]);
+ styles->styles[CSS_PSEUDO_ELEMENT_NONE] = composed;
}
for (pseudo_element = CSS_PSEUDO_ELEMENT_NONE + 1;
@@ -300,40 +306,20 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node
*n,
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
styles->styles[pseudo_element],
nscss_compute_font_size, NULL,
- &(styles->styles[pseudo_element]));
+ &composed);
if (error != CSS_OK) {
/* TODO: perhaps this shouldn't be quite so
* catastrophic? */
css_select_results_destroy(styles);
return NULL;
}
- }
-
- return styles;
-}
-
-/**
- * Get an initial style
- *
- * \param ctx CSS selection context
- * \return Pointer to partial computed style, or NULL on failure
- */
-static css_computed_style *nscss_get_initial_style(nscss_select_ctx *ctx)
-{
- css_computed_style *style;
- css_error error;
- error = css_computed_style_create(&style);
- if (error != CSS_OK)
- return NULL;
-
- error = css_computed_style_initialise(style, &selection_handler, ctx);
- if (error != CSS_OK) {
- css_computed_style_destroy(style);
- return NULL;
+ /* Replace select_results style with composed style */
+ css_computed_style_destroy(styles->styles[pseudo_element]);
+ styles->styles[pseudo_element] = composed;
}
- return style;
+ return styles;
}
/**
@@ -346,21 +332,26 @@ static css_computed_style *nscss_get_initial_style(nscss_select_ctx
*ctx)
css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
const css_computed_style *parent)
{
- css_computed_style *partial;
+ css_computed_style *partial, *composed;
css_error error;
- partial = nscss_get_initial_style(ctx);
- if (partial == NULL)
+ error = css_select_default_style(ctx->ctx,
+ &selection_handler, ctx, &partial);
+ if (error != CSS_OK) {
return NULL;
+ }
+ /* TODO: Do we really need to compose? Initial style shouldn't
+ * have any inherited properties. */
error = css_computed_style_compose(parent, partial,
- nscss_compute_font_size, NULL, &partial);
+ nscss_compute_font_size, NULL, &composed);
+ css_computed_style_destroy(partial);
if (error != CSS_OK) {
- css_computed_style_destroy(partial);
+ css_computed_style_destroy(composed);
return NULL;
}
- return partial;
+ return composed;
}
/**
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=2a8ce59c0e5b74449f8...
commit 2a8ce59c0e5b74449f8d9a1dc535c966fb3352d8
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Remove duplicate branch.
diff --git a/css/hints.c b/css/hints.c
index c8f5ebb..066212e 100644
--- a/css/hints.c
+++ b/css/hints.c
@@ -1578,14 +1578,6 @@ static css_error node_presentational_hint_color(
return CSS_PROPERTY_NOT_SET;
}
}
- } else if (dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_body)) {
- err = dom_element_get_attribute(node,
- corestring_dom_text, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
} else {
err = dom_element_get_attribute(node,
corestring_dom_color, &color);
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=f6750060c39eb36e888...
commit f6750060c39eb36e888e293d1fe6ed0b7e5a7cbc
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Tidy cellpadding hint handling.
diff --git a/css/hints.c b/css/hints.c
index 059b42b..c8f5ebb 100644
--- a/css/hints.c
+++ b/css/hints.c
@@ -832,7 +832,6 @@ static css_error node_presentational_hint_padding_trbl(
{
dom_string *name;
dom_exception exc;
- dom_string *cellpadding = NULL;
css_error result = CSS_PROPERTY_NOT_SET;
exc = dom_node_get_node_name(node, &name);
@@ -843,6 +842,8 @@ static css_error node_presentational_hint_padding_trbl(
dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
css_qname qs;
dom_node *tablenode = NULL;
+ dom_string *cellpadding = NULL;
+
qs.ns = NULL;
qs.name = lwc_string_ref(corestring_lwc_table);
if (named_ancestor_node(ctx, node, &qs,
@@ -866,20 +867,20 @@ static css_error node_presentational_hint_padding_trbl(
/* No need to unref tablenode, named_ancestor_node does not
* return a reffed node to the CSS
*/
- }
-
- dom_string_unref(name);
- if (cellpadding != NULL) {
- if (parse_dimension(dom_string_data(cellpadding), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_PADDING_SET;
- result = CSS_OK;
+ if (cellpadding != NULL) {
+ if (parse_dimension(dom_string_data(cellpadding), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_PADDING_SET;
+ result = CSS_OK;
+ }
+ dom_string_unref(cellpadding);
}
- dom_string_unref(cellpadding);
}
+ dom_string_unref(name);
+
return result;
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=73c7cdc5fadcda7a562...
commit 73c7cdc5fadcda7a562fbf34bf84e394c59e7534
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Split out presentational hints handling.
diff --git a/css/Makefile b/css/Makefile
index 1280d57..127dbaa 100644
--- a/css/Makefile
+++ b/css/Makefile
@@ -1,5 +1,5 @@
# CSS sources
-S_CSS := css.c dump.c internal.c select.c utils.c
+S_CSS := css.c dump.c internal.c hints.c select.c utils.c
S_CSS := $(addprefix css/,$(S_CSS))
diff --git a/css/hints.c b/css/hints.c
new file mode 100644
index 0000000..059b42b
--- /dev/null
+++ b/css/hints.c
@@ -0,0 +1,1794 @@
+/*
+ * Copyright 2009 John-Mark Bell <jmb(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/>.
+ */
+
+#include <string.h>
+#include <strings.h>
+
+#include "utils/nsoption.h"
+#include "utils/corestrings.h"
+#include "utils/log.h"
+#include "utils/nsurl.h"
+#include "utils/utils.h"
+
+#include "css/hints.h"
+#include "css/select.h"
+
+/******************************************************************************
+ * Utility functions *
+ ******************************************************************************/
+
+/**
+ * Determine if a given character is whitespace
+ *
+ * \param c Character to consider
+ * \return true if character is whitespace, false otherwise
+ */
+static bool isWhitespace(char c)
+{
+ return c == ' ' || c == '\t' || c == '\f' || c == '\r'
|| c == '\n';
+}
+
+/**
+ * Determine if a given character is a valid hex digit
+ *
+ * \param c Character to consider
+ * \return true if character is a valid hex digit, false otherwise
+ */
+static bool isHex(char c)
+{
+ return ('0' <= c && c <= '9') ||
+ ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F');
+}
+
+/**
+ * Convert a character representing a hex digit to the corresponding hex value
+ *
+ * \param c Character to convert
+ * \return Hex value represented by character
+ *
+ * \note This function assumes an ASCII-compatible character set
+ */
+static uint8_t charToHex(char c)
+{
+ /* 0-9 */
+ c -= '0';
+
+ /* A-F */
+ if (c > 9)
+ c -= 'A' - '9' - 1;
+
+ /* a-f */
+ if (c > 15)
+ c -= 'a' - 'A';
+
+ return c;
+}
+
+
+/******************************************************************************
+ * Common parsing functions *
+ ******************************************************************************/
+
+/**
+ * Parse a number string
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param maybe_negative Negative numbers permitted
+ * \param real Floating point numbers permitted
+ * \param value Pointer to location to receive numeric value
+ * \param consumed Pointer to location to receive number of input
+ * bytes consumed
+ * \return true on success, false on invalid input
+ */
+static bool parse_number(const char *data, bool maybe_negative, bool real,
+ css_fixed *value, size_t *consumed)
+{
+ size_t len;
+ const uint8_t *ptr;
+ int32_t intpart = 0;
+ int32_t fracpart = 0;
+ int32_t pwr = 1;
+ int sign = 1;
+
+ *consumed = 0;
+
+ len = strlen(data);
+ ptr = (const uint8_t *) data;
+
+ if (len == 0)
+ return false;
+
+ /* Skip leading whitespace */
+ while (len > 0 && isWhitespace(ptr[0])) {
+ len--;
+ ptr++;
+ }
+
+ if (len == 0)
+ return false;
+
+ /* Extract sign, if any */
+ if (ptr[0] == '+') {
+ len--;
+ ptr++;
+ } else if (ptr[0] == '-' && maybe_negative) {
+ sign = -1;
+ len--;
+ ptr++;
+ }
+
+ if (len == 0)
+ return false;
+
+ /* Must have a digit [0,9] */
+ if ('0' > ptr[0] || ptr[0] > '9')
+ return false;
+
+ /* Now extract intpart, assuming base 10 */
+ while (len > 0) {
+ /* Stop on first non-digit */
+ if (ptr[0] < '0' || '9' < ptr[0])
+ break;
+
+ /* Prevent overflow of 'intpart'; proper clamping below */
+ if (intpart < (1 << 22)) {
+ intpart *= 10;
+ intpart += ptr[0] - '0';
+ }
+ ptr++;
+ len--;
+ }
+
+ /* And fracpart, again, assuming base 10 */
+ if (real && len > 1 && ptr[0] == '.' &&
+ ('0' <= ptr[1] && ptr[1] <= '9')) {
+ ptr++;
+ len--;
+
+ while (len > 0) {
+ if (ptr[0] < '0' || '9' < ptr[0])
+ break;
+
+ if (pwr < 1000000) {
+ pwr *= 10;
+ fracpart *= 10;
+ fracpart += ptr[0] - '0';
+ }
+ ptr++;
+ len--;
+ }
+
+ fracpart = ((1 << 10) * fracpart + pwr/2) / pwr;
+ if (fracpart >= (1 << 10)) {
+ intpart++;
+ fracpart &= (1 << 10) - 1;
+ }
+ }
+
+ if (sign > 0) {
+ /* If the result is larger than we can represent,
+ * then clamp to the maximum value we can store. */
+ if (intpart >= (1 << 21)) {
+ intpart = (1 << 21) - 1;
+ fracpart = (1 << 10) - 1;
+ }
+ } else {
+ /* If the negated result is smaller than we can represent
+ * then clamp to the minimum value we can store. */
+ if (intpart >= (1 << 21)) {
+ intpart = -(1 << 21);
+ fracpart = 0;
+ } else {
+ intpart = -intpart;
+ if (fracpart) {
+ fracpart = (1 << 10) - fracpart;
+ intpart--;
+ }
+ }
+ }
+
+ *value = (intpart << 10) | fracpart;
+
+ *consumed = ptr - (const uint8_t *) data;
+
+ return true;
+}
+
+/**
+ * Parse a dimension string
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param strict Whether to enforce strict parsing rules
+ * \param length Pointer to location to receive dimension's length
+ * \param unit Pointer to location to receive dimension's unit
+ * \return true on success, false on invalid input
+ */
+static bool parse_dimension(const char *data, bool strict, css_fixed *length,
+ css_unit *unit)
+{
+ size_t len;
+ size_t read;
+ css_fixed value;
+
+ len = strlen(data);
+
+ if (parse_number(data, false, true, &value, &read) == false)
+ return false;
+
+ if (strict && value < INTTOFIX(1))
+ return false;
+
+ *length = value;
+
+ if (len > read && data[read] == '%')
+ *unit = CSS_UNIT_PCT;
+ else
+ *unit = CSS_UNIT_PX;
+
+ return true;
+}
+
+/**
+ * Mapping of colour name to CSS color
+ */
+struct colour_map {
+ const char *name;
+ css_color color;
+};
+
+/**
+ * Name comparator for named colour matching
+ *
+ * \param a Name to match
+ * \param b Colour map entry to consider
+ * \return 0 on match,
+ * < 0 if a < b,
+ * > 0 if b > a.
+ */
+static int cmp_colour_name(const void *a, const void *b)
+{
+ const char *aa = a;
+ const struct colour_map *bb = b;
+
+ return strcasecmp(aa, bb->name);
+}
+
+/**
+ * Parse a named colour
+ *
+ * \param name Name to parse
+ * \param result Pointer to location to receive css_color
+ * \return true on success, false on invalid input
+ */
+static bool parse_named_colour(const char *name, css_color *result)
+{
+ static const struct colour_map named_colours[] = {
+ { "aliceblue", 0xfff0f8ff },
+ { "antiquewhite", 0xfffaebd7 },
+ { "aqua", 0xff00ffff },
+ { "aquamarine", 0xff7fffd4 },
+ { "azure", 0xfff0ffff },
+ { "beige", 0xfff5f5dc },
+ { "bisque", 0xffffe4c4 },
+ { "black", 0xff000000 },
+ { "blanchedalmond", 0xffffebcd },
+ { "blue", 0xff0000ff },
+ { "blueviolet", 0xff8a2be2 },
+ { "brown", 0xffa52a2a },
+ { "burlywood", 0xffdeb887 },
+ { "cadetblue", 0xff5f9ea0 },
+ { "chartreuse", 0xff7fff00 },
+ { "chocolate", 0xffd2691e },
+ { "coral", 0xffff7f50 },
+ { "cornflowerblue", 0xff6495ed },
+ { "cornsilk", 0xfffff8dc },
+ { "crimson", 0xffdc143c },
+ { "cyan", 0xff00ffff },
+ { "darkblue", 0xff00008b },
+ { "darkcyan", 0xff008b8b },
+ { "darkgoldenrod", 0xffb8860b },
+ { "darkgray", 0xffa9a9a9 },
+ { "darkgreen", 0xff006400 },
+ { "darkgrey", 0xffa9a9a9 },
+ { "darkkhaki", 0xffbdb76b },
+ { "darkmagenta", 0xff8b008b },
+ { "darkolivegreen", 0xff556b2f },
+ { "darkorange", 0xffff8c00 },
+ { "darkorchid", 0xff9932cc },
+ { "darkred", 0xff8b0000 },
+ { "darksalmon", 0xffe9967a },
+ { "darkseagreen", 0xff8fbc8f },
+ { "darkslateblue", 0xff483d8b },
+ { "darkslategray", 0xff2f4f4f },
+ { "darkslategrey", 0xff2f4f4f },
+ { "darkturquoise", 0xff00ced1 },
+ { "darkviolet", 0xff9400d3 },
+ { "deeppink", 0xffff1493 },
+ { "deepskyblue", 0xff00bfff },
+ { "dimgray", 0xff696969 },
+ { "dimgrey", 0xff696969 },
+ { "dodgerblue", 0xff1e90ff },
+ { "feldspar", 0xffd19275 },
+ { "firebrick", 0xffb22222 },
+ { "floralwhite", 0xfffffaf0 },
+ { "forestgreen", 0xff228b22 },
+ { "fuchsia", 0xffff00ff },
+ { "gainsboro", 0xffdcdcdc },
+ { "ghostwhite", 0xfff8f8ff },
+ { "gold", 0xffffd700 },
+ { "goldenrod", 0xffdaa520 },
+ { "gray", 0xff808080 },
+ { "green", 0xff008000 },
+ { "greenyellow", 0xffadff2f },
+ { "grey", 0xff808080 },
+ { "honeydew", 0xfff0fff0 },
+ { "hotpink", 0xffff69b4 },
+ { "indianred", 0xffcd5c5c },
+ { "indigo", 0xff4b0082 },
+ { "ivory", 0xfffffff0 },
+ { "khaki", 0xfff0e68c },
+ { "lavender", 0xffe6e6fa },
+ { "lavenderblush", 0xfffff0f5 },
+ { "lawngreen", 0xff7cfc00 },
+ { "lemonchiffon", 0xfffffacd },
+ { "lightblue", 0xffadd8e6 },
+ { "lightcoral", 0xfff08080 },
+ { "lightcyan", 0xffe0ffff },
+ { "lightgoldenrodyellow", 0xfffafad2 },
+ { "lightgray", 0xffd3d3d3 },
+ { "lightgreen", 0xff90ee90 },
+ { "lightgrey", 0xffd3d3d3 },
+ { "lightpink", 0xffffb6c1 },
+ { "lightsalmon", 0xffffa07a },
+ { "lightseagreen", 0xff20b2aa },
+ { "lightskyblue", 0xff87cefa },
+ { "lightslateblue", 0xff8470ff },
+ { "lightslategray", 0xff778899 },
+ { "lightslategrey", 0xff778899 },
+ { "lightsteelblue", 0xffb0c4de },
+ { "lightyellow", 0xffffffe0 },
+ { "lime", 0xff00ff00 },
+ { "limegreen", 0xff32cd32 },
+ { "linen", 0xfffaf0e6 },
+ { "magenta", 0xffff00ff },
+ { "maroon", 0xff800000 },
+ { "mediumaquamarine", 0xff66cdaa },
+ { "mediumblue", 0xff0000cd },
+ { "mediumorchid", 0xffba55d3 },
+ { "mediumpurple", 0xff9370db },
+ { "mediumseagreen", 0xff3cb371 },
+ { "mediumslateblue", 0xff7b68ee },
+ { "mediumspringgreen", 0xff00fa9a },
+ { "mediumturquoise", 0xff48d1cc },
+ { "mediumvioletred", 0xffc71585 },
+ { "midnightblue", 0xff191970 },
+ { "mintcream", 0xfff5fffa },
+ { "mistyrose", 0xffffe4e1 },
+ { "moccasin", 0xffffe4b5 },
+ { "navajowhite", 0xffffdead },
+ { "navy", 0xff000080 },
+ { "oldlace", 0xfffdf5e6 },
+ { "olive", 0xff808000 },
+ { "olivedrab", 0xff6b8e23 },
+ { "orange", 0xffffa500 },
+ { "orangered", 0xffff4500 },
+ { "orchid", 0xffda70d6 },
+ { "palegoldenrod", 0xffeee8aa },
+ { "palegreen", 0xff98fb98 },
+ { "paleturquoise", 0xffafeeee },
+ { "palevioletred", 0xffdb7093 },
+ { "papayawhip", 0xffffefd5 },
+ { "peachpuff", 0xffffdab9 },
+ { "peru", 0xffcd853f },
+ { "pink", 0xffffc0cb },
+ { "plum", 0xffdda0dd },
+ { "powderblue", 0xffb0e0e6 },
+ { "purple", 0xff800080 },
+ { "red", 0xffff0000 },
+ { "rosybrown", 0xffbc8f8f },
+ { "royalblue", 0xff4169e1 },
+ { "saddlebrown", 0xff8b4513 },
+ { "salmon", 0xfffa8072 },
+ { "sandybrown", 0xfff4a460 },
+ { "seagreen", 0xff2e8b57 },
+ { "seashell", 0xfffff5ee },
+ { "sienna", 0xffa0522d },
+ { "silver", 0xffc0c0c0 },
+ { "skyblue", 0xff87ceeb },
+ { "slateblue", 0xff6a5acd },
+ { "slategray", 0xff708090 },
+ { "slategrey", 0xff708090 },
+ { "snow", 0xfffffafa },
+ { "springgreen", 0xff00ff7f },
+ { "steelblue", 0xff4682b4 },
+ { "tan", 0xffd2b48c },
+ { "teal", 0xff008080 },
+ { "thistle", 0xffd8bfd8 },
+ { "tomato", 0xffff6347 },
+ { "turquoise", 0xff40e0d0 },
+ { "violet", 0xffee82ee },
+ { "violetred", 0xffd02090 },
+ { "wheat", 0xfff5deb3 },
+ { "white", 0xffffffff },
+ { "whitesmoke", 0xfff5f5f5 },
+ { "yellow", 0xffffff00 },
+ { "yellowgreen", 0xff9acd32 }
+ };
+ const struct colour_map *entry;
+
+ entry = bsearch(name, named_colours,
+ sizeof(named_colours) / sizeof(named_colours[0]),
+ sizeof(named_colours[0]),
+ cmp_colour_name);
+
+ if (entry != NULL)
+ *result = entry->color;
+
+ return entry != NULL;
+}
+
+/**
+ * Parser for colours specified in attribute values.
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param result Pointer to location to receive resulting css_color
+ * \return true on success, false on invalid input
+ */
+bool nscss_parse_colour(const char *data, css_color *result)
+{
+ size_t len = strlen(data);
+ uint8_t r, g, b;
+
+ /* 2 */
+ if (len == 0)
+ return false;
+
+ /* 3 */
+ if (len == SLEN("transparent") && strcasecmp(data,
"transparent") == 0)
+ return false;
+
+ /* 4 */
+ if (parse_named_colour(data, result))
+ return true;
+
+ /** \todo Implement HTML5's utterly insane legacy colour parsing */
+
+ if (data[0] == '#') {
+ data++;
+ len--;
+ }
+
+ if (len == 3 && isHex(data[0]) && isHex(data[1]) &&
isHex(data[2])) {
+ r = charToHex(data[0]);
+ g = charToHex(data[1]);
+ b = charToHex(data[2]);
+
+ r |= (r << 4);
+ g |= (g << 4);
+ b |= (b << 4);
+
+ *result = (0xff << 24) | (r << 16) | (g << 8) | b;
+
+ return true;
+ } else if (len == 6 && isHex(data[0]) && isHex(data[1]) &&
+ isHex(data[2]) && isHex(data[3]) && isHex(data[4]) &&
+ isHex(data[5])) {
+ r = (charToHex(data[0]) << 4) | charToHex(data[1]);
+ g = (charToHex(data[2]) << 4) | charToHex(data[3]);
+ b = (charToHex(data[4]) << 4) | charToHex(data[5]);
+
+ *result = (0xff << 24) | (r << 16) | (g << 8) | b;
+
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Parse a font \@size attribute
+ *
+ * \param size Data to parse (NUL-terminated)
+ * \param val Pointer to location to receive enum value
+ * \param len Pointer to location to receive length
+ * \param unit Pointer to location to receive unit
+ * \return True on success, false on failure
+ */
+static bool parse_font_size(const char *size, uint8_t *val,
+ css_fixed *len, css_unit *unit)
+{
+ static const uint8_t size_map[] = {
+ CSS_FONT_SIZE_XX_SMALL,
+ CSS_FONT_SIZE_SMALL,
+ CSS_FONT_SIZE_MEDIUM,
+ CSS_FONT_SIZE_LARGE,
+ CSS_FONT_SIZE_X_LARGE,
+ CSS_FONT_SIZE_XX_LARGE,
+ CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */
+ };
+
+ const char *p = size;
+ char mode;
+ int value = 0;
+
+ /* Skip whitespace */
+ while (*p != '\0' && isWhitespace(*p))
+ p++;
+
+ mode = *p;
+
+ /* Skip +/- */
+ if (mode == '+' || mode == '-')
+ p++;
+
+ /* Need at least one digit */
+ if (*p < '0' || *p > '9') {
+ return false;
+ }
+
+ /* Consume digits, computing value */
+ while ('0' <= *p && *p <= '9') {
+ value = value * 10 + (*p - '0');
+ p++;
+ }
+
+ /* Resolve relative sizes */
+ if (mode == '+')
+ value += 3;
+ else if (mode == '-')
+ value = 3 - value;
+
+ /* Clamp to range [1,7] */
+ if (value < 1)
+ value = 1;
+ else if (value > 7)
+ value = 7;
+
+ if (value == 7) {
+ /* Manufacture xxx-large */
+ *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))),
+ F_10);
+ } else {
+ /* Len is irrelevant */
+ *len = 0;
+ }
+
+ *unit = CSS_UNIT_PT;
+ *val = size_map[value - 1];
+
+ return true;
+}
+
+
+/******************************************************************************
+ * Presentational hint handlers *
+ ******************************************************************************/
+
+static css_error node_presentational_hint_vertical_align(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *valign = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_col) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_thead) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tbody) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tfoot) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_valign, &valign);
+ if (err != DOM_NO_ERR || valign == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_top)) {
+ hint->status = CSS_VERTICAL_ALIGN_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_middle)) {
+ hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_bottom)) {
+ hint->status = CSS_VERTICAL_ALIGN_BOTTOM;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_baseline)) {
+ hint->status = CSS_VERTICAL_ALIGN_BASELINE;
+ } else {
+ dom_string_unref(valign);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(valign);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_applet) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_embed) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_object)) {
+ /** \todo input[type=image][align=*] - $11.3.3 */
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &valign);
+ if (err != DOM_NO_ERR || valign == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_top)) {
+ hint->status = CSS_VERTICAL_ALIGN_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_bottom) ||
+ dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_baseline)) {
+ hint->status = CSS_VERTICAL_ALIGN_BASELINE;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_texttop)) {
+ hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_absmiddle) ||
+ dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_abscenter)) {
+ hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
+ } else {
+ dom_string_unref(valign);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(valign);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_text_align(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *align = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_p) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h1) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h2) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h3) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h4) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h5) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h6)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR || align == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_caption)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (align == NULL || dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (align != NULL)
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_div) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_thead) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tbody) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tfoot) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_th)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR || align == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ /* Tables usually reset alignment */
+ hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC;
+
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else {
+ dom_string_unref(name);
+
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+}
+
+static css_error node_presentational_hint_padding_trbl(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+ dom_string *cellpadding = NULL;
+ css_error result = CSS_PROPERTY_NOT_SET;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ exc = dom_element_get_attribute(tablenode,
+ corestring_dom_cellpadding,
+ &cellpadding);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ }
+
+ dom_string_unref(name);
+
+ if (cellpadding != NULL) {
+ if (parse_dimension(dom_string_data(cellpadding), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_PADDING_SET;
+ result = CSS_OK;
+ }
+ dom_string_unref(cellpadding);
+ }
+
+ return result;
+}
+
+static css_error node_presentational_hint_margin_rl(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint,
+ uint32_t property)
+{
+ dom_string *n;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &n);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(n, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(n, corestring_lwc_applet)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_hspace, &n);
+ if (exc != DOM_NO_ERR) {
+ return CSS_BADPARM;
+ }
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(n), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ dom_string_unref(n);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_table) ||
+ dom_string_caseless_lwc_isequal(n, corestring_lwc_align)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_align, &n);
+ if (exc != DOM_NO_ERR) {
+ return CSS_BADPARM;
+ }
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_center) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_abscenter) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_middle) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_absmiddle)) {
+ hint->status = CSS_MARGIN_AUTO;
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(n);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_hr)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_align, &n);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_left)) {
+ if (property == CSS_PROP_MARGIN_LEFT) {
+ hint->data.length.value = 0;
+ hint->data.length.unit = CSS_UNIT_PX;
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ hint->status = CSS_MARGIN_AUTO;
+ }
+ } else if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_center)) {
+ hint->status = CSS_MARGIN_AUTO;
+ } else if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_right)) {
+ if (property == CSS_PROP_MARGIN_RIGHT) {
+ hint->data.length.value = 0;
+ hint->data.length.unit = CSS_UNIT_PX;
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ hint->status = CSS_MARGIN_AUTO;
+ }
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ dom_string_unref(n);
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(n);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_margin_tb(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name, *vspace = NULL;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ exc = dom_element_get_attribute(node, corestring_dom_vspace,
+ &vspace);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+
+ dom_string_unref(name);
+
+ if (vspace == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(vspace), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ dom_string_unref(vspace);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(vspace);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_border_trbl_width(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+ dom_string *width = NULL;
+ bool is_table_cell = false;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+ if (tablenode != NULL) {
+ exc = dom_element_get_attribute(tablenode,
+ corestring_dom_border, &width);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ is_table_cell = true;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ exc = dom_element_get_attribute(node, corestring_dom_border,
+ &width);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+
+ dom_string_unref(name);
+
+ if (width == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(width), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ if (is_table_cell &&
+ INTTOFIX(0) !=
+ hint->data.length.value) {
+ hint->data.length.value = INTTOFIX(1);
+ hint->data.length.unit = CSS_UNIT_PX;
+ }
+ hint->status = CSS_BORDER_WIDTH_WIDTH;
+ } else {
+ dom_string_unref(width);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(width);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_border_trbl_style(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ bool has_border = false;
+
+ exc = dom_element_has_attribute(tablenode,
+ corestring_dom_border,
+ &has_border);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+
+ if (has_border) {
+ hint->status = CSS_BORDER_STYLE_INSET;
+ dom_string_unref(name);
+ return CSS_OK;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ bool has_border = false;
+
+ exc = dom_element_has_attribute(node,
+ corestring_dom_border,
+ &has_border);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+
+ if (has_border) {
+ hint->status = CSS_BORDER_STYLE_OUTSET;
+ dom_string_unref(name);
+ return CSS_OK;
+ }
+ }
+
+ dom_string_unref(name);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_border_trbl_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *bordercolor = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_bordercolor,
+ &bordercolor);
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_bordercolor,
+ &bordercolor);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (bordercolor == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (nscss_parse_colour((const char *)dom_string_data(bordercolor),
+ &hint->data.color)) {
+ hint->status = CSS_BORDER_COLOR_COLOR;
+ dom_string_unref(bordercolor);
+ return CSS_OK;
+ }
+
+ dom_string_unref(bordercolor);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_border_spacing(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *cellspacing = NULL;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_table)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_cellspacing, &cellspacing);
+ if ((err != DOM_NO_ERR) || (cellspacing == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+
+ if (parse_dimension((const char *)dom_string_data(cellspacing),
+ false,
+ &hint->data.position.h.value,
+ &hint->data.position.h.unit)) {
+
+ hint->data.position.v = hint->data.position.h;
+ hint->status = CSS_BORDER_SPACING_SET;
+
+ dom_string_unref(cellspacing);
+ return CSS_OK;
+ }
+
+ dom_string_unref(cellspacing);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_width(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *width = NULL;
+ dom_exception err;
+ bool textarea = false;
+ bool input = false;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_hr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_table) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_width, &width);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_textarea)) {
+ textarea = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_cols, &width);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_input)) {
+ input = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_size, &width);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (width == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_dimension((const char *)dom_string_data(width),
+ false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_WIDTH_SET;
+ dom_string_unref(width);
+
+ if (textarea) {
+ hint->data.length.unit = CSS_UNIT_EX;
+ }
+
+ if (input) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_type, &width);
+ if (err != DOM_NO_ERR) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if ((width == NULL) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_text) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_search) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_file) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_password)) {
+ hint->data.length.unit = CSS_UNIT_EX;
+ }
+ dom_string_unref(width);
+ }
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(width);
+ return CSS_PROPERTY_NOT_SET;
+
+}
+
+static css_error node_presentational_hint_height(nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *height = NULL;
+ dom_exception err;
+ bool textarea = false;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_height, &height);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_textarea)) {
+ textarea = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_rows, &height);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (height == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_dimension((const char *)dom_string_data(height),
+ false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_HEIGHT_SET;
+
+ if (textarea) {
+ hint->data.length.unit = CSS_UNIT_EM;
+ }
+
+ dom_string_unref(height);
+ return CSS_OK;
+ }
+
+ dom_string_unref(height);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_font_size(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *size;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_font)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_size, &size);
+ if ((err != DOM_NO_ERR) || (size == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_font_size((const char *)dom_string_data(size),
+ &hint->status,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ dom_string_unref(size);
+ return CSS_OK;
+ }
+
+ dom_string_unref(size);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_float(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *align;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ /** \todo input[type=image][align=*] - $11.3.3 */
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_table) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_applet) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_embed) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_iframe) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_img) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_object)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_align, &align);
+ if ((err != DOM_NO_ERR) || (align == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_FLOAT_LEFT;
+ dom_string_unref(align);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_FLOAT_RIGHT;
+ dom_string_unref(align);
+ return CSS_OK;
+ }
+
+ dom_string_unref(align);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ css_error error;
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *color;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ if (dom_string_caseless_lwc_isequal(node_name, corestring_lwc_a)) {
+ /* find body node */
+ css_qname qs;
+ dom_node *bodynode = NULL;
+ bool is_visited;
+
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_body);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&bodynode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ /* deal with missing body ancestor */
+ if (bodynode == NULL) {
+ dom_string_unref(node_name);
+ return CSS_BADPARM;
+ }
+
+ error = node_is_visited(ctx, node, &is_visited);
+ if (error != CSS_OK)
+ return error;
+
+ if (is_visited) {
+ err = dom_element_get_attribute(bodynode,
+ corestring_dom_vlink, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ } else {
+ err = dom_element_get_attribute(bodynode,
+ corestring_dom_link, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ }
+ } else if (dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_body)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_text, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ } else {
+ err = dom_element_get_attribute(node,
+ corestring_dom_color, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ }
+
+ if (!nscss_parse_colour((const char *)dom_string_data(color),
+ &hint->data.color)) {
+ dom_string_unref(color);
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ hint->status = CSS_COLOR_COLOR;
+
+ dom_string_unref(color);
+ dom_string_unref(node_name);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_caption_side(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *align = NULL;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_caption)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_align, &align);
+ if ((err != DOM_NO_ERR) || (align == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align, corestring_lwc_bottom)) {
+ hint->status = CSS_CAPTION_SIDE_BOTTOM;
+ dom_string_unref(align);
+ return CSS_OK;
+ }
+
+ dom_string_unref(align);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_background_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *bgcolor;
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_bgcolor, &bgcolor);
+ if ((err != DOM_NO_ERR) || (bgcolor == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (nscss_parse_colour((const char *)dom_string_data(bgcolor),
+ &hint->data.color)) {
+ hint->status = CSS_BACKGROUND_COLOR_COLOR;
+ dom_string_unref(bgcolor);
+ return CSS_OK;
+ }
+
+ dom_string_unref(bgcolor);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_background_image(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *atr_val;
+ nserror error;
+ nsurl *url;
+ lwc_string *iurl;
+ lwc_error lerror;
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_background, &atr_val);
+ if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ error = nsurl_join(ctx->base_url,
+ (const char *)dom_string_data(atr_val), &url);
+
+ dom_string_unref(atr_val);
+
+ if (error != NSERROR_OK) {
+ return CSS_NOMEM;
+ }
+
+ lerror = lwc_intern_string(nsurl_access(url),
+ nsurl_length(url), &iurl);
+
+ nsurl_unref(url);
+
+ if (lerror == lwc_error_oom) {
+ return CSS_NOMEM;
+ }
+
+ if (lerror == lwc_error_ok) {
+ hint->data.string = iurl;
+ hint->status = CSS_BACKGROUND_IMAGE_IMAGE;
+ return CSS_OK;
+ }
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+/* Exported function, documeted in css/hints.h */
+css_error node_presentational_hint(void *pw, void *node,
+ uint32_t property, css_hint *hint)
+{
+
+ switch (property) {
+ case CSS_PROP_BACKGROUND_IMAGE:
+ return node_presentational_hint_background_image(pw, node, hint);
+
+ case CSS_PROP_BACKGROUND_COLOR:
+ return node_presentational_hint_background_color(pw, node, hint);
+ case CSS_PROP_CAPTION_SIDE:
+ return node_presentational_hint_caption_side(pw, node, hint);
+
+ case CSS_PROP_COLOR:
+ return node_presentational_hint_color(pw, node, hint);
+
+ case CSS_PROP_FLOAT:
+ return node_presentational_hint_float(pw, node, hint);
+
+ case CSS_PROP_FONT_SIZE:
+ return node_presentational_hint_font_size(pw, node, hint);
+
+ case CSS_PROP_HEIGHT:
+ return node_presentational_hint_height(pw, node, hint);
+
+ case CSS_PROP_WIDTH:
+ return node_presentational_hint_width(pw, node, hint);
+
+ case CSS_PROP_BORDER_SPACING:
+ return node_presentational_hint_border_spacing(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_COLOR :
+ case CSS_PROP_BORDER_RIGHT_COLOR :
+ case CSS_PROP_BORDER_BOTTOM_COLOR :
+ case CSS_PROP_BORDER_LEFT_COLOR :
+ return node_presentational_hint_border_trbl_color(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_STYLE :
+ case CSS_PROP_BORDER_RIGHT_STYLE :
+ case CSS_PROP_BORDER_BOTTOM_STYLE :
+ case CSS_PROP_BORDER_LEFT_STYLE :
+ return node_presentational_hint_border_trbl_style(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_WIDTH :
+ case CSS_PROP_BORDER_RIGHT_WIDTH :
+ case CSS_PROP_BORDER_BOTTOM_WIDTH :
+ case CSS_PROP_BORDER_LEFT_WIDTH :
+ return node_presentational_hint_border_trbl_width(pw, node, hint);
+
+ case CSS_PROP_MARGIN_TOP :
+ case CSS_PROP_MARGIN_BOTTOM :
+ return node_presentational_hint_margin_tb(pw, node, hint);
+
+ case CSS_PROP_MARGIN_RIGHT:
+ case CSS_PROP_MARGIN_LEFT:
+ return node_presentational_hint_margin_rl(pw, node, hint, property);
+
+ case CSS_PROP_PADDING_TOP:
+ case CSS_PROP_PADDING_RIGHT :
+ case CSS_PROP_PADDING_BOTTOM :
+ case CSS_PROP_PADDING_LEFT:
+ return node_presentational_hint_padding_trbl(pw, node, hint);
+
+ case CSS_PROP_TEXT_ALIGN:
+ return node_presentational_hint_text_align(pw, node, hint);
+
+ case CSS_PROP_VERTICAL_ALIGN:
+ return node_presentational_hint_vertical_align(pw, node, hint);
+ }
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
diff --git a/css/hints.h b/css/hints.h
new file mode 100644
index 0000000..68d4c10
--- /dev/null
+++ b/css/hints.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 John-Mark Bell <jmb(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/>.
+ */
+
+#ifndef NETSURF_CSS_HINTS_H_
+#define NETSURF_CSS_HINTS_H_
+
+#include <stdint.h>
+
+#include "css/css.h"
+
+
+
+
+/**
+ * Callback to retrieve presentational hints for a node
+ *
+ * \param pw HTML document
+ * \param node DOM node
+ * \param property CSS property to retrieve
+ * \param hint Pointer to hint object to populate
+ * \return CSS_OK on success,
+ * CSS_PROPERTY_NOT_SET if there is no hint for the requested property,
+ * CSS_NOMEM on memory exhaustion.
+ */
+css_error node_presentational_hint(
+ void *pw,
+ void *node,
+ uint32_t property,
+ css_hint *hint);
+
+bool nscss_parse_colour(const char *data, css_color *result);
+
+#endif
diff --git a/css/select.c b/css/select.c
index 85c32b5..c9e5f7e 100644
--- a/css/select.c
+++ b/css/select.c
@@ -17,28 +17,23 @@
*/
#include <assert.h>
-#include <stdbool.h>
#include <string.h>
#include <strings.h>
-#include "content/content_protected.h"
#include "content/urldb.h"
#include "desktop/system_colour.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/log.h"
-#include "utils/utils.h"
#include "css/internal.h"
+#include "css/hints.h"
#include "css/select.h"
-#include "css/utils.h"
static css_error node_name(void *pw, void *node, css_qname *qname);
static css_error node_classes(void *pw, void *node,
lwc_string ***classes, uint32_t *n_classes);
static css_error node_id(void *pw, void *node, lwc_string **id);
-static css_error named_ancestor_node(void *pw, void *node,
- const css_qname *qname, void **ancestor);
static css_error named_parent_node(void *pw, void *node,
const css_qname *qname, void **parent);
static css_error named_sibling_node(void *pw, void *node,
@@ -78,7 +73,6 @@ static css_error node_count_siblings(void *pw, void *node,
bool same_name, bool after, int32_t *count);
static css_error node_is_empty(void *pw, void *node, bool *match);
static css_error node_is_link(void *pw, void *node, bool *match);
-static css_error node_is_visited(void *pw, void *node, bool *match);
static css_error node_is_hover(void *pw, void *node, bool *match);
static css_error node_is_active(void *pw, void *node, bool *match);
static css_error node_is_focus(void *pw, void *node, bool *match);
@@ -88,8 +82,6 @@ static css_error node_is_checked(void *pw, void *node, bool *match);
static css_error node_is_target(void *pw, void *node, bool *match);
static css_error node_is_lang(void *pw, void *node,
lwc_string *lang, bool *match);
-static css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hint);
static css_error set_libcss_node_data(void *pw, void *node,
@@ -97,18 +89,9 @@ static css_error set_libcss_node_data(void *pw, void *node,
static css_error get_libcss_node_data(void *pw, void *node,
void **libcss_node_data);
-static int cmp_colour_name(const void *a, const void *b);
-static bool parse_named_colour(const char *data, css_color *result);
-static bool parse_dimension(const char *data, bool strict,
- css_fixed *length, css_unit *unit);
-static bool parse_number(const char *data, bool non_negative, bool real,
- css_fixed *value, size_t *consumed);
-static bool parse_font_size(const char *size, uint8_t *val,
- css_fixed *len, css_unit *unit);
+static css_error nscss_compute_font_size(void *pw, const css_hint *parent,
+ css_hint *size);
-static bool isWhitespace(char c);
-static bool isHex(char c);
-static uint8_t charToHex(char c);
/**
* Selection callback table for libcss
@@ -465,64 +448,6 @@ css_error nscss_compute_font_size(void *pw, const css_hint *parent,
return CSS_OK;
}
-/**
- * Parser for colours specified in attribute values.
- *
- * \param data Data to parse (NUL-terminated)
- * \param result Pointer to location to receive resulting css_color
- * \return true on success, false on invalid input
- */
-bool nscss_parse_colour(const char *data, css_color *result)
-{
- size_t len = strlen(data);
- uint8_t r, g, b;
-
- /* 2 */
- if (len == 0)
- return false;
-
- /* 3 */
- if (len == SLEN("transparent") && strcasecmp(data,
"transparent") == 0)
- return false;
-
- /* 4 */
- if (parse_named_colour(data, result))
- return true;
-
- /** \todo Implement HTML5's utterly insane legacy colour parsing */
-
- if (data[0] == '#') {
- data++;
- len--;
- }
-
- if (len == 3 && isHex(data[0]) && isHex(data[1]) &&
isHex(data[2])) {
- r = charToHex(data[0]);
- g = charToHex(data[1]);
- b = charToHex(data[2]);
-
- r |= (r << 4);
- g |= (g << 4);
- b |= (b << 4);
-
- *result = (0xff << 24) | (r << 16) | (g << 8) | b;
-
- return true;
- } else if (len == 6 && isHex(data[0]) && isHex(data[1]) &&
- isHex(data[2]) && isHex(data[3]) && isHex(data[4]) &&
- isHex(data[5])) {
- r = (charToHex(data[0]) << 4) | charToHex(data[1]);
- g = (charToHex(data[2]) << 4) | charToHex(data[3]);
- b = (charToHex(data[4]) << 4) | charToHex(data[5]);
-
- *result = (0xff << 24) | (r << 16) | (g << 8) | b;
-
- return true;
- }
-
- return false;
-}
-
/******************************************************************************
* Style selection callbacks *
******************************************************************************/
@@ -1844,1794 +1769,86 @@ css_error node_is_lang(void *pw, void *node,
return CSS_OK;
}
-static css_error
-node_presentational_hint_vertical_align(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *valign = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_col) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_thead) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tbody) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tfoot) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- err = dom_element_get_attribute(node,
- corestring_dom_valign, &valign);
- if (err != DOM_NO_ERR || valign == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_top)) {
- hint->status = CSS_VERTICAL_ALIGN_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_middle)) {
- hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_bottom)) {
- hint->status = CSS_VERTICAL_ALIGN_BOTTOM;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_baseline)) {
- hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- } else {
- dom_string_unref(valign);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(valign);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_applet) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_embed) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_object)) {
- /** \todo input[type=image][align=*] - $11.3.3 */
- err = dom_element_get_attribute(node,
- corestring_dom_align, &valign);
- if (err != DOM_NO_ERR || valign == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_top)) {
- hint->status = CSS_VERTICAL_ALIGN_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_bottom) ||
- dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_baseline)) {
- hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_texttop)) {
- hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_absmiddle) ||
- dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_abscenter)) {
- hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- } else {
- dom_string_unref(valign);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(valign);
- dom_string_unref(name);
-
- return CSS_OK;
- }
-
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_text_align(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
+/**
+ * Callback to retrieve the User-Agent defaults for a CSS property.
+ *
+ * \param pw HTML document
+ * \param property Property to retrieve defaults for
+ * \param hint Pointer to hint object to populate
+ * \return CSS_OK on success,
+ * CSS_INVALID if the property should not have a user-agent default.
+ */
+css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
{
- dom_string *name;
- dom_string *align = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_p) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h1) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h2) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h3) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h4) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h5) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h6)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR || align == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
-
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_caption)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (align == NULL || dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (align != NULL)
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_div) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_thead) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tbody) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tfoot) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_th)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR || align == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
+ if (property == CSS_PROP_COLOR) {
+ hint->data.color = 0xff000000;
+ hint->status = CSS_COLOR_COLOR;
+ } else if (property == CSS_PROP_FONT_FAMILY) {
+ hint->data.strings = NULL;
+ switch (nsoption_int(font_default)) {
+ case PLOT_FONT_FAMILY_SANS_SERIF:
+ hint->status = CSS_FONT_FAMILY_SANS_SERIF;
+ break;
+ case PLOT_FONT_FAMILY_SERIF:
+ hint->status = CSS_FONT_FAMILY_SERIF;
+ break;
+ case PLOT_FONT_FAMILY_MONOSPACE:
+ hint->status = CSS_FONT_FAMILY_MONOSPACE;
+ break;
+ case PLOT_FONT_FAMILY_CURSIVE:
+ hint->status = CSS_FONT_FAMILY_CURSIVE;
+ break;
+ case PLOT_FONT_FAMILY_FANTASY:
+ hint->status = CSS_FONT_FAMILY_FANTASY;
+ break;
}
-
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- /* Tables usually reset alignment */
- hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC;
-
- dom_string_unref(name);
-
- return CSS_OK;
+ } else if (property == CSS_PROP_QUOTES) {
+ /** \todo Not exactly useful :) */
+ hint->data.strings = NULL;
+ hint->status = CSS_QUOTES_NONE;
+ } else if (property == CSS_PROP_VOICE_FAMILY) {
+ /** \todo Fix this when we have voice-family done */
+ hint->data.strings = NULL;
+ hint->status = 0;
} else {
- dom_string_unref(name);
-
- return CSS_PROPERTY_NOT_SET;
- }
-
-}
-
-static css_error
-node_presentational_hint_padding_trbl(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_exception exc;
- dom_string *cellpadding = NULL;
- css_error result = CSS_PROPERTY_NOT_SET;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- exc = dom_element_get_attribute(tablenode,
- corestring_dom_cellpadding,
- &cellpadding);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
+ return CSS_INVALID;
}
-
- dom_string_unref(name);
- if (cellpadding != NULL) {
- if (parse_dimension(dom_string_data(cellpadding), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_PADDING_SET;
- result = CSS_OK;
- }
- dom_string_unref(cellpadding);
- }
-
- return result;
+ return CSS_OK;
}
-static css_error
-node_presentational_hint_margin_rl(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint,
- uint32_t property)
+css_error set_libcss_node_data(void *pw, void *node, void *libcss_node_data)
{
- dom_string *n;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &n);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(n, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(n, corestring_lwc_applet)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_hspace, &n);
- if (exc != DOM_NO_ERR) {
- return CSS_BADPARM;
- }
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(n), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_MARGIN_SET;
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
- dom_string_unref(n);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_table) ||
- dom_string_caseless_lwc_isequal(n, corestring_lwc_align)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_align, &n);
- if (exc != DOM_NO_ERR) {
- return CSS_BADPARM;
- }
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_center) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_abscenter) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_middle) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_absmiddle)) {
- hint->status = CSS_MARGIN_AUTO;
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(n);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_hr)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_align, &n);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_left)) {
- if (property == CSS_PROP_MARGIN_LEFT) {
- hint->data.length.value = 0;
- hint->data.length.unit = CSS_UNIT_PX;
- hint->status = CSS_MARGIN_SET;
- } else {
- hint->status = CSS_MARGIN_AUTO;
- }
- } else if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_center)) {
- hint->status = CSS_MARGIN_AUTO;
- } else if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_right)) {
- if (property == CSS_PROP_MARGIN_RIGHT) {
- hint->data.length.value = 0;
- hint->data.length.unit = CSS_UNIT_PX;
- hint->status = CSS_MARGIN_SET;
- } else {
- hint->status = CSS_MARGIN_AUTO;
- }
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
- dom_string_unref(n);
-
- return CSS_OK;
- }
-
- dom_string_unref(n);
-
- return CSS_PROPERTY_NOT_SET;
-}
+ dom_node *n = node;
+ dom_exception err;
+ void *old_node_data;
-static css_error
-node_presentational_hint_margin_tb(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name, *vspace = NULL;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- exc = dom_element_get_attribute(node, corestring_dom_vspace,
- &vspace);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
-
- dom_string_unref(name);
-
- if (vspace == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(vspace), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_MARGIN_SET;
- } else {
- dom_string_unref(vspace);
- return CSS_PROPERTY_NOT_SET;
+ /* Set this node's node data */
+ err = dom_node_set_user_data(n,
+ corestring_dom___ns_key_libcss_node_data,
+ libcss_node_data, nscss_dom_user_data_handler,
+ (void *) &old_node_data);
+ if (err != DOM_NO_ERR) {
+ return CSS_NOMEM;
}
- dom_string_unref(vspace);
+ assert(old_node_data == NULL);
return CSS_OK;
}
-static css_error
-node_presentational_hint_border_trbl_width(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
+css_error get_libcss_node_data(void *pw, void *node, void **libcss_node_data)
{
- dom_string *name;
- dom_exception exc;
- dom_string *width = NULL;
- bool is_table_cell = false;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
- if (tablenode != NULL) {
- exc = dom_element_get_attribute(tablenode,
- corestring_dom_border, &width);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
- is_table_cell = true;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- exc = dom_element_get_attribute(node, corestring_dom_border,
- &width);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
-
- dom_string_unref(name);
-
- if (width == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(width), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- if (is_table_cell &&
- INTTOFIX(0) !=
- hint->data.length.value) {
- hint->data.length.value = INTTOFIX(1);
- hint->data.length.unit = CSS_UNIT_PX;
- }
- hint->status = CSS_BORDER_WIDTH_WIDTH;
- } else {
- dom_string_unref(width);
- return CSS_PROPERTY_NOT_SET;
- }
+ dom_node *n = node;
+ dom_exception err;
- dom_string_unref(width);
+ /* Get this node's node data */
+ err = dom_node_get_user_data(n,
+ corestring_dom___ns_key_libcss_node_data,
+ libcss_node_data);
+ if (err != DOM_NO_ERR) {
+ return CSS_NOMEM;
+ }
return CSS_OK;
}
-
-static css_error
-node_presentational_hint_border_trbl_style(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
-
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- bool has_border = false;
-
- exc = dom_element_has_attribute(tablenode,
- corestring_dom_border,
- &has_border);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
-
- if (has_border) {
- hint->status = CSS_BORDER_STYLE_INSET;
- dom_string_unref(name);
- return CSS_OK;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- bool has_border = false;
-
- exc = dom_element_has_attribute(node,
- corestring_dom_border,
- &has_border);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
-
- if (has_border) {
- hint->status = CSS_BORDER_STYLE_OUTSET;
- dom_string_unref(name);
- return CSS_OK;
- }
- }
-
- dom_string_unref(name);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_border_trbl_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *bordercolor = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
-
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- err = dom_element_get_attribute(node,
- corestring_dom_bordercolor,
- &bordercolor);
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
-
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- err = dom_element_get_attribute(node,
- corestring_dom_bordercolor,
- &bordercolor);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (bordercolor == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (nscss_parse_colour((const char *)dom_string_data(bordercolor),
- &hint->data.color)) {
- hint->status = CSS_BORDER_COLOR_COLOR;
- dom_string_unref(bordercolor);
- return CSS_OK;
- }
-
- dom_string_unref(bordercolor);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_border_spacing(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *cellspacing = NULL;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_table)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node,
- corestring_dom_cellspacing, &cellspacing);
- if ((err != DOM_NO_ERR) || (cellspacing == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
-
- if (parse_dimension((const char *)dom_string_data(cellspacing),
- false,
- &hint->data.position.h.value,
- &hint->data.position.h.unit)) {
-
- hint->data.position.v = hint->data.position.h;
- hint->status = CSS_BORDER_SPACING_SET;
-
- dom_string_unref(cellspacing);
- return CSS_OK;
- }
-
- dom_string_unref(cellspacing);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_width(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *width = NULL;
- dom_exception err;
- bool textarea = false;
- bool input = false;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_hr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_table) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- err = dom_element_get_attribute(node,
- corestring_dom_width, &width);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_textarea)) {
- textarea = true;
- err = dom_element_get_attribute(node,
- corestring_dom_cols, &width);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_input)) {
- input = true;
- err = dom_element_get_attribute(node,
- corestring_dom_size, &width);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (width == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_dimension((const char *)dom_string_data(width),
- false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_WIDTH_SET;
- dom_string_unref(width);
-
- if (textarea) {
- hint->data.length.unit = CSS_UNIT_EX;
- }
-
- if (input) {
- err = dom_element_get_attribute(node,
- corestring_dom_type, &width);
- if (err != DOM_NO_ERR) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if ((width == NULL) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_text) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_search) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_file) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_password)) {
- hint->data.length.unit = CSS_UNIT_EX;
- }
- dom_string_unref(width);
- }
-
- return CSS_OK;
- }
-
- dom_string_unref(width);
- return CSS_PROPERTY_NOT_SET;
-
-}
-
-static css_error
-node_presentational_hint_height(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *height = NULL;
- dom_exception err;
- bool textarea = false;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- err = dom_element_get_attribute(node,
- corestring_dom_height, &height);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_textarea)) {
- textarea = true;
- err = dom_element_get_attribute(node,
- corestring_dom_rows, &height);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (height == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_dimension((const char *)dom_string_data(height),
- false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_HEIGHT_SET;
-
- if (textarea) {
- hint->data.length.unit = CSS_UNIT_EM;
- }
-
- dom_string_unref(height);
- return CSS_OK;
- }
-
- dom_string_unref(height);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_font_size(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *size;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_font)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_size, &size);
- if ((err != DOM_NO_ERR) || (size == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_font_size((const char *)dom_string_data(size),
- &hint->status,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- dom_string_unref(size);
- return CSS_OK;
- }
-
- dom_string_unref(size);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_float(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *align;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- /** \todo input[type=image][align=*] - $11.3.3 */
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_table) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_applet) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_embed) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_iframe) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_img) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_object)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_align, &align);
- if ((err != DOM_NO_ERR) || (align == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_FLOAT_LEFT;
- dom_string_unref(align);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_FLOAT_RIGHT;
- dom_string_unref(align);
- return CSS_OK;
- }
-
- dom_string_unref(align);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- css_error error;
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *color;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- if (dom_string_caseless_lwc_isequal(node_name, corestring_lwc_a)) {
- /* find body node */
- css_qname qs;
- dom_node *bodynode = NULL;
- bool is_visited;
-
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_body);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&bodynode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- /* deal with missing body ancestor */
- if (bodynode == NULL) {
- dom_string_unref(node_name);
- return CSS_BADPARM;
- }
-
- error = node_is_visited(ctx, node, &is_visited);
- if (error != CSS_OK)
- return error;
-
- if (is_visited) {
- err = dom_element_get_attribute(bodynode,
- corestring_dom_vlink, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- } else {
- err = dom_element_get_attribute(bodynode,
- corestring_dom_link, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- }
- } else if (dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_body)) {
- err = dom_element_get_attribute(node,
- corestring_dom_text, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- } else {
- err = dom_element_get_attribute(node,
- corestring_dom_color, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- }
-
- if (!nscss_parse_colour((const char *)dom_string_data(color),
- &hint->data.color)) {
- dom_string_unref(color);
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- hint->status = CSS_COLOR_COLOR;
-
- dom_string_unref(color);
- dom_string_unref(node_name);
-
- return CSS_OK;
-}
-
-static css_error
-node_presentational_hint_caption_side(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *align = NULL;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_caption)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_align, &align);
- if ((err != DOM_NO_ERR) || (align == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align, corestring_lwc_bottom)) {
- hint->status = CSS_CAPTION_SIDE_BOTTOM;
- dom_string_unref(align);
- return CSS_OK;
- }
-
- dom_string_unref(align);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_background_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *bgcolor;
-
- err = dom_element_get_attribute(node,
- corestring_dom_bgcolor, &bgcolor);
- if ((err != DOM_NO_ERR) || (bgcolor == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (nscss_parse_colour((const char *)dom_string_data(bgcolor),
- &hint->data.color)) {
- hint->status = CSS_BACKGROUND_COLOR_COLOR;
- dom_string_unref(bgcolor);
- return CSS_OK;
- }
-
- dom_string_unref(bgcolor);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_background_image(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *atr_val;
- nserror error;
- nsurl *url;
- lwc_string *iurl;
- lwc_error lerror;
-
- err = dom_element_get_attribute(node,
- corestring_dom_background, &atr_val);
- if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- error = nsurl_join(ctx->base_url,
- (const char *)dom_string_data(atr_val), &url);
-
- dom_string_unref(atr_val);
-
- if (error != NSERROR_OK) {
- return CSS_NOMEM;
- }
-
- lerror = lwc_intern_string(nsurl_access(url),
- nsurl_length(url), &iurl);
-
- nsurl_unref(url);
-
- if (lerror == lwc_error_oom) {
- return CSS_NOMEM;
- }
-
- if (lerror == lwc_error_ok) {
- hint->data.string = iurl;
- hint->status = CSS_BACKGROUND_IMAGE_IMAGE;
- return CSS_OK;
- }
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-/**
- * Callback to retrieve presentational hints for a node
- *
- * \param pw HTML document
- * \param node DOM node
- * \param property CSS property to retrieve
- * \param hint Pointer to hint object to populate
- * \return CSS_OK on success,
- * CSS_PROPERTY_NOT_SET if there is no hint for the requested property,
- * CSS_NOMEM on memory exhaustion.
- */
-css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint)
-{
-
- switch (property) {
- case CSS_PROP_BACKGROUND_IMAGE:
- return node_presentational_hint_background_image(pw, node, hint);
-
- case CSS_PROP_BACKGROUND_COLOR:
- return node_presentational_hint_background_color(pw, node, hint);
- case CSS_PROP_CAPTION_SIDE:
- return node_presentational_hint_caption_side(pw, node, hint);
-
- case CSS_PROP_COLOR:
- return node_presentational_hint_color(pw, node, hint);
-
- case CSS_PROP_FLOAT:
- return node_presentational_hint_float(pw, node, hint);
-
- case CSS_PROP_FONT_SIZE:
- return node_presentational_hint_font_size(pw, node, hint);
-
- case CSS_PROP_HEIGHT:
- return node_presentational_hint_height(pw, node, hint);
-
- case CSS_PROP_WIDTH:
- return node_presentational_hint_width(pw, node, hint);
-
- case CSS_PROP_BORDER_SPACING:
- return node_presentational_hint_border_spacing(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_COLOR :
- case CSS_PROP_BORDER_RIGHT_COLOR :
- case CSS_PROP_BORDER_BOTTOM_COLOR :
- case CSS_PROP_BORDER_LEFT_COLOR :
- return node_presentational_hint_border_trbl_color(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_STYLE :
- case CSS_PROP_BORDER_RIGHT_STYLE :
- case CSS_PROP_BORDER_BOTTOM_STYLE :
- case CSS_PROP_BORDER_LEFT_STYLE :
- return node_presentational_hint_border_trbl_style(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_WIDTH :
- case CSS_PROP_BORDER_RIGHT_WIDTH :
- case CSS_PROP_BORDER_BOTTOM_WIDTH :
- case CSS_PROP_BORDER_LEFT_WIDTH :
- return node_presentational_hint_border_trbl_width(pw, node, hint);
-
- case CSS_PROP_MARGIN_TOP :
- case CSS_PROP_MARGIN_BOTTOM :
- return node_presentational_hint_margin_tb(pw, node, hint);
-
- case CSS_PROP_MARGIN_RIGHT:
- case CSS_PROP_MARGIN_LEFT:
- return node_presentational_hint_margin_rl(pw, node, hint, property);
-
- case CSS_PROP_PADDING_TOP:
- case CSS_PROP_PADDING_RIGHT :
- case CSS_PROP_PADDING_BOTTOM :
- case CSS_PROP_PADDING_LEFT:
- return node_presentational_hint_padding_trbl(pw, node, hint);
-
- case CSS_PROP_TEXT_ALIGN:
- return node_presentational_hint_text_align(pw, node, hint);
-
- case CSS_PROP_VERTICAL_ALIGN:
- return node_presentational_hint_vertical_align(pw, node, hint);
- }
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-/**
- * Callback to retrieve the User-Agent defaults for a CSS property.
- *
- * \param pw HTML document
- * \param property Property to retrieve defaults for
- * \param hint Pointer to hint object to populate
- * \return CSS_OK on success,
- * CSS_INVALID if the property should not have a user-agent default.
- */
-css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
-{
- if (property == CSS_PROP_COLOR) {
- hint->data.color = 0xff000000;
- hint->status = CSS_COLOR_COLOR;
- } else if (property == CSS_PROP_FONT_FAMILY) {
- hint->data.strings = NULL;
- switch (nsoption_int(font_default)) {
- case PLOT_FONT_FAMILY_SANS_SERIF:
- hint->status = CSS_FONT_FAMILY_SANS_SERIF;
- break;
- case PLOT_FONT_FAMILY_SERIF:
- hint->status = CSS_FONT_FAMILY_SERIF;
- break;
- case PLOT_FONT_FAMILY_MONOSPACE:
- hint->status = CSS_FONT_FAMILY_MONOSPACE;
- break;
- case PLOT_FONT_FAMILY_CURSIVE:
- hint->status = CSS_FONT_FAMILY_CURSIVE;
- break;
- case PLOT_FONT_FAMILY_FANTASY:
- hint->status = CSS_FONT_FAMILY_FANTASY;
- break;
- }
- } else if (property == CSS_PROP_QUOTES) {
- /** \todo Not exactly useful :) */
- hint->data.strings = NULL;
- hint->status = CSS_QUOTES_NONE;
- } else if (property == CSS_PROP_VOICE_FAMILY) {
- /** \todo Fix this when we have voice-family done */
- hint->data.strings = NULL;
- hint->status = 0;
- } else {
- return CSS_INVALID;
- }
-
- return CSS_OK;
-}
-
-css_error set_libcss_node_data(void *pw, void *node, void *libcss_node_data)
-{
- dom_node *n = node;
- dom_exception err;
- void *old_node_data;
-
- /* Set this node's node data */
- err = dom_node_set_user_data(n,
- corestring_dom___ns_key_libcss_node_data,
- libcss_node_data, nscss_dom_user_data_handler,
- (void *) &old_node_data);
- if (err != DOM_NO_ERR) {
- return CSS_NOMEM;
- }
-
- assert(old_node_data == NULL);
-
- return CSS_OK;
-}
-
-css_error get_libcss_node_data(void *pw, void *node, void **libcss_node_data)
-{
- dom_node *n = node;
- dom_exception err;
-
- /* Get this node's node data */
- err = dom_node_get_user_data(n,
- corestring_dom___ns_key_libcss_node_data,
- libcss_node_data);
- if (err != DOM_NO_ERR) {
- return CSS_NOMEM;
- }
-
- return CSS_OK;
-}
-
-/**
- * Mapping of colour name to CSS color
- */
-struct colour_map {
- const char *name;
- css_color color;
-};
-
-/**
- * Name comparator for named colour matching
- *
- * \param a Name to match
- * \param b Colour map entry to consider
- * \return 0 on match,
- * < 0 if a < b,
- * > 0 if b > a.
- */
-int cmp_colour_name(const void *a, const void *b)
-{
- const char *aa = a;
- const struct colour_map *bb = b;
-
- return strcasecmp(aa, bb->name);
-}
-
-/**
- * Parse a named colour
- *
- * \param name Name to parse
- * \param result Pointer to location to receive css_color
- * \return true on success, false on invalid input
- */
-bool parse_named_colour(const char *name, css_color *result)
-{
- static const struct colour_map named_colours[] = {
- { "aliceblue", 0xfff0f8ff },
- { "antiquewhite", 0xfffaebd7 },
- { "aqua", 0xff00ffff },
- { "aquamarine", 0xff7fffd4 },
- { "azure", 0xfff0ffff },
- { "beige", 0xfff5f5dc },
- { "bisque", 0xffffe4c4 },
- { "black", 0xff000000 },
- { "blanchedalmond", 0xffffebcd },
- { "blue", 0xff0000ff },
- { "blueviolet", 0xff8a2be2 },
- { "brown", 0xffa52a2a },
- { "burlywood", 0xffdeb887 },
- { "cadetblue", 0xff5f9ea0 },
- { "chartreuse", 0xff7fff00 },
- { "chocolate", 0xffd2691e },
- { "coral", 0xffff7f50 },
- { "cornflowerblue", 0xff6495ed },
- { "cornsilk", 0xfffff8dc },
- { "crimson", 0xffdc143c },
- { "cyan", 0xff00ffff },
- { "darkblue", 0xff00008b },
- { "darkcyan", 0xff008b8b },
- { "darkgoldenrod", 0xffb8860b },
- { "darkgray", 0xffa9a9a9 },
- { "darkgreen", 0xff006400 },
- { "darkgrey", 0xffa9a9a9 },
- { "darkkhaki", 0xffbdb76b },
- { "darkmagenta", 0xff8b008b },
- { "darkolivegreen", 0xff556b2f },
- { "darkorange", 0xffff8c00 },
- { "darkorchid", 0xff9932cc },
- { "darkred", 0xff8b0000 },
- { "darksalmon", 0xffe9967a },
- { "darkseagreen", 0xff8fbc8f },
- { "darkslateblue", 0xff483d8b },
- { "darkslategray", 0xff2f4f4f },
- { "darkslategrey", 0xff2f4f4f },
- { "darkturquoise", 0xff00ced1 },
- { "darkviolet", 0xff9400d3 },
- { "deeppink", 0xffff1493 },
- { "deepskyblue", 0xff00bfff },
- { "dimgray", 0xff696969 },
- { "dimgrey", 0xff696969 },
- { "dodgerblue", 0xff1e90ff },
- { "feldspar", 0xffd19275 },
- { "firebrick", 0xffb22222 },
- { "floralwhite", 0xfffffaf0 },
- { "forestgreen", 0xff228b22 },
- { "fuchsia", 0xffff00ff },
- { "gainsboro", 0xffdcdcdc },
- { "ghostwhite", 0xfff8f8ff },
- { "gold", 0xffffd700 },
- { "goldenrod", 0xffdaa520 },
- { "gray", 0xff808080 },
- { "green", 0xff008000 },
- { "greenyellow", 0xffadff2f },
- { "grey", 0xff808080 },
- { "honeydew", 0xfff0fff0 },
- { "hotpink", 0xffff69b4 },
- { "indianred", 0xffcd5c5c },
- { "indigo", 0xff4b0082 },
- { "ivory", 0xfffffff0 },
- { "khaki", 0xfff0e68c },
- { "lavender", 0xffe6e6fa },
- { "lavenderblush", 0xfffff0f5 },
- { "lawngreen", 0xff7cfc00 },
- { "lemonchiffon", 0xfffffacd },
- { "lightblue", 0xffadd8e6 },
- { "lightcoral", 0xfff08080 },
- { "lightcyan", 0xffe0ffff },
- { "lightgoldenrodyellow", 0xfffafad2 },
- { "lightgray", 0xffd3d3d3 },
- { "lightgreen", 0xff90ee90 },
- { "lightgrey", 0xffd3d3d3 },
- { "lightpink", 0xffffb6c1 },
- { "lightsalmon", 0xffffa07a },
- { "lightseagreen", 0xff20b2aa },
- { "lightskyblue", 0xff87cefa },
- { "lightslateblue", 0xff8470ff },
- { "lightslategray", 0xff778899 },
- { "lightslategrey", 0xff778899 },
- { "lightsteelblue", 0xffb0c4de },
- { "lightyellow", 0xffffffe0 },
- { "lime", 0xff00ff00 },
- { "limegreen", 0xff32cd32 },
- { "linen", 0xfffaf0e6 },
- { "magenta", 0xffff00ff },
- { "maroon", 0xff800000 },
- { "mediumaquamarine", 0xff66cdaa },
- { "mediumblue", 0xff0000cd },
- { "mediumorchid", 0xffba55d3 },
- { "mediumpurple", 0xff9370db },
- { "mediumseagreen", 0xff3cb371 },
- { "mediumslateblue", 0xff7b68ee },
- { "mediumspringgreen", 0xff00fa9a },
- { "mediumturquoise", 0xff48d1cc },
- { "mediumvioletred", 0xffc71585 },
- { "midnightblue", 0xff191970 },
- { "mintcream", 0xfff5fffa },
- { "mistyrose", 0xffffe4e1 },
- { "moccasin", 0xffffe4b5 },
- { "navajowhite", 0xffffdead },
- { "navy", 0xff000080 },
- { "oldlace", 0xfffdf5e6 },
- { "olive", 0xff808000 },
- { "olivedrab", 0xff6b8e23 },
- { "orange", 0xffffa500 },
- { "orangered", 0xffff4500 },
- { "orchid", 0xffda70d6 },
- { "palegoldenrod", 0xffeee8aa },
- { "palegreen", 0xff98fb98 },
- { "paleturquoise", 0xffafeeee },
- { "palevioletred", 0xffdb7093 },
- { "papayawhip", 0xffffefd5 },
- { "peachpuff", 0xffffdab9 },
- { "peru", 0xffcd853f },
- { "pink", 0xffffc0cb },
- { "plum", 0xffdda0dd },
- { "powderblue", 0xffb0e0e6 },
- { "purple", 0xff800080 },
- { "red", 0xffff0000 },
- { "rosybrown", 0xffbc8f8f },
- { "royalblue", 0xff4169e1 },
- { "saddlebrown", 0xff8b4513 },
- { "salmon", 0xfffa8072 },
- { "sandybrown", 0xfff4a460 },
- { "seagreen", 0xff2e8b57 },
- { "seashell", 0xfffff5ee },
- { "sienna", 0xffa0522d },
- { "silver", 0xffc0c0c0 },
- { "skyblue", 0xff87ceeb },
- { "slateblue", 0xff6a5acd },
- { "slategray", 0xff708090 },
- { "slategrey", 0xff708090 },
- { "snow", 0xfffffafa },
- { "springgreen", 0xff00ff7f },
- { "steelblue", 0xff4682b4 },
- { "tan", 0xffd2b48c },
- { "teal", 0xff008080 },
- { "thistle", 0xffd8bfd8 },
- { "tomato", 0xffff6347 },
- { "turquoise", 0xff40e0d0 },
- { "violet", 0xffee82ee },
- { "violetred", 0xffd02090 },
- { "wheat", 0xfff5deb3 },
- { "white", 0xffffffff },
- { "whitesmoke", 0xfff5f5f5 },
- { "yellow", 0xffffff00 },
- { "yellowgreen", 0xff9acd32 }
- };
- const struct colour_map *entry;
-
- entry = bsearch(name, named_colours,
- sizeof(named_colours) / sizeof(named_colours[0]),
- sizeof(named_colours[0]),
- cmp_colour_name);
-
- if (entry != NULL)
- *result = entry->color;
-
- return entry != NULL;
-}
-
-/**
- * Parse a dimension string
- *
- * \param data Data to parse (NUL-terminated)
- * \param strict Whether to enforce strict parsing rules
- * \param length Pointer to location to receive dimension's length
- * \param unit Pointer to location to receive dimension's unit
- * \return true on success, false on invalid input
- */
-bool parse_dimension(const char *data, bool strict, css_fixed *length,
- css_unit *unit)
-{
- size_t len;
- size_t read;
- css_fixed value;
-
- len = strlen(data);
-
- if (parse_number(data, false, true, &value, &read) == false)
- return false;
-
- if (strict && value < INTTOFIX(1))
- return false;
-
- *length = value;
-
- if (len > read && data[read] == '%')
- *unit = CSS_UNIT_PCT;
- else
- *unit = CSS_UNIT_PX;
-
- return true;
-}
-
-/**
- * Parse a number string
- *
- * \param data Data to parse (NUL-terminated)
- * \param maybe_negative Negative numbers permitted
- * \param real Floating point numbers permitted
- * \param value Pointer to location to receive numeric value
- * \param consumed Pointer to location to receive number of input
- * bytes consumed
- * \return true on success, false on invalid input
- */
-bool parse_number(const char *data, bool maybe_negative, bool real,
- css_fixed *value, size_t *consumed)
-{
- size_t len;
- const uint8_t *ptr;
- int32_t intpart = 0;
- int32_t fracpart = 0;
- int32_t pwr = 1;
- int sign = 1;
-
- *consumed = 0;
-
- len = strlen(data);
- ptr = (const uint8_t *) data;
-
- if (len == 0)
- return false;
-
- /* Skip leading whitespace */
- while (len > 0 && isWhitespace(ptr[0])) {
- len--;
- ptr++;
- }
-
- if (len == 0)
- return false;
-
- /* Extract sign, if any */
- if (ptr[0] == '+') {
- len--;
- ptr++;
- } else if (ptr[0] == '-' && maybe_negative) {
- sign = -1;
- len--;
- ptr++;
- }
-
- if (len == 0)
- return false;
-
- /* Must have a digit [0,9] */
- if ('0' > ptr[0] || ptr[0] > '9')
- return false;
-
- /* Now extract intpart, assuming base 10 */
- while (len > 0) {
- /* Stop on first non-digit */
- if (ptr[0] < '0' || '9' < ptr[0])
- break;
-
- /* Prevent overflow of 'intpart'; proper clamping below */
- if (intpart < (1 << 22)) {
- intpart *= 10;
- intpart += ptr[0] - '0';
- }
- ptr++;
- len--;
- }
-
- /* And fracpart, again, assuming base 10 */
- if (real && len > 1 && ptr[0] == '.' &&
- ('0' <= ptr[1] && ptr[1] <= '9')) {
- ptr++;
- len--;
-
- while (len > 0) {
- if (ptr[0] < '0' || '9' < ptr[0])
- break;
-
- if (pwr < 1000000) {
- pwr *= 10;
- fracpart *= 10;
- fracpart += ptr[0] - '0';
- }
- ptr++;
- len--;
- }
-
- fracpart = ((1 << 10) * fracpart + pwr/2) / pwr;
- if (fracpart >= (1 << 10)) {
- intpart++;
- fracpart &= (1 << 10) - 1;
- }
- }
-
- if (sign > 0) {
- /* If the result is larger than we can represent,
- * then clamp to the maximum value we can store. */
- if (intpart >= (1 << 21)) {
- intpart = (1 << 21) - 1;
- fracpart = (1 << 10) - 1;
- }
- } else {
- /* If the negated result is smaller than we can represent
- * then clamp to the minimum value we can store. */
- if (intpart >= (1 << 21)) {
- intpart = -(1 << 21);
- fracpart = 0;
- } else {
- intpart = -intpart;
- if (fracpart) {
- fracpart = (1 << 10) - fracpart;
- intpart--;
- }
- }
- }
-
- *value = (intpart << 10) | fracpart;
-
- *consumed = ptr - (const uint8_t *) data;
-
- return true;
-}
-
-/**
- * Parse a font \@size attribute
- *
- * \param size Data to parse (NUL-terminated)
- * \param val Pointer to location to receive enum value
- * \param len Pointer to location to receive length
- * \param unit Pointer to location to receive unit
- * \return True on success, false on failure
- */
-bool parse_font_size(const char *size, uint8_t *val,
- css_fixed *len, css_unit *unit)
-{
- static const uint8_t size_map[] = {
- CSS_FONT_SIZE_XX_SMALL,
- CSS_FONT_SIZE_SMALL,
- CSS_FONT_SIZE_MEDIUM,
- CSS_FONT_SIZE_LARGE,
- CSS_FONT_SIZE_X_LARGE,
- CSS_FONT_SIZE_XX_LARGE,
- CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */
- };
-
- const char *p = size;
- char mode;
- int value = 0;
-
- /* Skip whitespace */
- while (*p != '\0' && isWhitespace(*p))
- p++;
-
- mode = *p;
-
- /* Skip +/- */
- if (mode == '+' || mode == '-')
- p++;
-
- /* Need at least one digit */
- if (*p < '0' || *p > '9') {
- return false;
- }
-
- /* Consume digits, computing value */
- while ('0' <= *p && *p <= '9') {
- value = value * 10 + (*p - '0');
- p++;
- }
-
- /* Resolve relative sizes */
- if (mode == '+')
- value += 3;
- else if (mode == '-')
- value = 3 - value;
-
- /* Clamp to range [1,7] */
- if (value < 1)
- value = 1;
- else if (value > 7)
- value = 7;
-
- if (value == 7) {
- /* Manufacture xxx-large */
- *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))),
- F_10);
- } else {
- /* Len is irrelevant */
- *len = 0;
- }
-
- *unit = CSS_UNIT_PT;
- *val = size_map[value - 1];
-
- return true;
-}
-
-/******************************************************************************
- * Utility functions *
- ******************************************************************************/
-
-/**
- * Determine if a given character is whitespace
- *
- * \param c Character to consider
- * \return true if character is whitespace, false otherwise
- */
-bool isWhitespace(char c)
-{
- return c == ' ' || c == '\t' || c == '\f' || c == '\r'
|| c == '\n';
-}
-
-/**
- * Determine if a given character is a valid hex digit
- *
- * \param c Character to consider
- * \return true if character is a valid hex digit, false otherwise
- */
-bool isHex(char c)
-{
- return ('0' <= c && c <= '9') ||
- ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F');
-}
-
-/**
- * Convert a character representing a hex digit to the corresponding hex value
- *
- * \param c Character to convert
- * \return Hex value represented by character
- *
- * \note This function assumes an ASCII-compatible character set
- */
-uint8_t charToHex(char c)
-{
- /* 0-9 */
- c -= '0';
-
- /* A-F */
- if (c > 9)
- c -= 'A' - '9' - 1;
-
- /* a-f */
- if (c > 15)
- c -= 'a' - 'A';
-
- return c;
-}
-
diff --git a/css/select.h b/css/select.h
index 13b9e12..0e0be95 100644
--- a/css/select.h
+++ b/css/select.h
@@ -49,9 +49,9 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
const css_computed_style *parent);
-css_error nscss_compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
-bool nscss_parse_colour(const char *data, css_color *result);
+css_error named_ancestor_node(void *pw, void *node,
+ const css_qname *qname, void **ancestor);
+css_error node_is_visited(void *pw, void *node, bool *match);
#endif
diff --git a/render/box_construct.c b/render/box_construct.c
index 2ad5eb2..8d98573 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -36,8 +36,9 @@
#include "utils/config.h"
#include "content/content_protected.h"
#include "css/css.h"
-#include "css/utils.h"
+#include "css/hints.h"
#include "css/select.h"
+#include "css/utils.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/locale.h"
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=e612366e1f50be45593...
commit e612366e1f50be4559349a3bc754fc875b5af330
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Update to test shared computed styles version of libcss.
diff --git a/css/select.c b/css/select.c
index e88d3f6..85c32b5 100644
--- a/css/select.c
+++ b/css/select.c
@@ -290,7 +290,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node
*n,
error = css_computed_style_compose(ctx->parent_style,
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
nscss_compute_font_size, NULL,
- styles->styles[CSS_PSEUDO_ELEMENT_NONE]);
+ &(styles->styles[CSS_PSEUDO_ELEMENT_NONE]));
if (error != CSS_OK) {
css_select_results_destroy(styles);
return NULL;
@@ -317,7 +317,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node
*n,
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
styles->styles[pseudo_element],
nscss_compute_font_size, NULL,
- styles->styles[pseudo_element]);
+ &(styles->styles[pseudo_element]));
if (error != CSS_OK) {
/* TODO: perhaps this shouldn't be quite so
* catastrophic? */
@@ -371,7 +371,7 @@ css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
return NULL;
error = css_computed_style_compose(parent, partial,
- nscss_compute_font_size, NULL, partial);
+ nscss_compute_font_size, NULL, &partial);
if (error != CSS_OK) {
css_computed_style_destroy(partial);
return NULL;
-----------------------------------------------------------------------
Summary of changes:
!NetSurf/Resources/ca-bundle | 1143 ++-
Docs/BUILDING-BeOS | 41 +-
Docs/Doxyfile | 3 +-
Docs/UnimplementedJavascript.txt | 1802 ++++
Docs/env.sh | 10 +-
Docs/netsurf-gtk.1 | 2 +-
Makefile | 4 +-
Makefile.config.example | 2 +
amiga/Makefile.target | 5 +-
amiga/bitmap.h | 1 +
amiga/clipboard.c | 2 +-
amiga/clipboard.h | 2 +-
amiga/context_menu.c | 1340 ---
amiga/ctxmenu.c | 557 +
amiga/ctxmenu.h | 92 +
amiga/dist/NetSurf.guide | 25 +-
amiga/font.c | 234 +-
amiga/font_scan.c | 3 +-
amiga/gui.c | 261 +-
amiga/gui.h | 21 +-
amiga/gui_options.c | 75 +-
amiga/libs.c | 16 +-
amiga/menu.c | 148 +-
amiga/menu.h | 7 +-
amiga/options.h | 5 +-
amiga/os3support.c | 35 +-
amiga/os3support.h | 5 +
amiga/plotters.c | 30 +-
amiga/rtg.c | 25 +-
amiga/selectmenu.c | 200 +
amiga/{context_menu.h => selectmenu.h} | 20 +-
amiga/tree.c | 15 +-
beos/Makefile.target | 5 +-
beos/about.cpp | 30 +-
beos/bitmap.cpp | 26 +-
beos/gui.cpp | 62 +-
beos/res/messages | 1 -
beos/scaffolding.cpp | 121 +-
beos/scaffolding.h | 2 +-
content/fetch.h | 1 +
content/fetchers/curl.c | 54 +-
content/llcache.c | 19 +
content/llcache.h | 3 +
desktop/browser.c | 46 +-
desktop/browser.h | 30 +-
desktop/netsurf.c | 3 +
desktop/options.h | 11 +
framebuffer/res/fonts/glyph_data | 35 +-
gtk/scaffolding.c | 13 +-
javascript/Makefile | 91 +-
javascript/WebIDL/Makefile | 10 +-
javascript/WebIDL/cssom.idl | 157 +
javascript/WebIDL/dom-parsing.idl | 35 +
javascript/WebIDL/html.idl | 155 +-
javascript/duktape/Console.bnd | 6 +-
javascript/duktape/Document.bnd | 256 +-
javascript/duktape/Element.bnd | 216 +-
javascript/duktape/Event.bnd | 145 +
javascript/duktape/HTMLAnchorElement.bnd | 39 +
javascript/duktape/HTMLAppletElement.bnd | 30 +
javascript/duktape/HTMLAreaElement.bnd | 26 +
javascript/duktape/HTMLBRElement.bnd | 14 +
javascript/duktape/HTMLBaseElement.bnd | 17 +
javascript/duktape/HTMLBodyElement.bnd | 24 +
javascript/duktape/HTMLButtonElement.bnd | 18 +
javascript/duktape/HTMLCollection.bnd | 6 +-
javascript/duktape/HTMLDivElement.bnd | 14 +
javascript/duktape/HTMLElement.bnd | 153 +
javascript/duktape/HTMLFontElement.bnd | 20 +
javascript/duktape/HTMLFormElement.bnd | 26 +
javascript/duktape/HTMLFrameElement.bnd | 35 +
javascript/duktape/HTMLFrameSetElement.bnd | 17 +
javascript/duktape/HTMLHRElement.bnd | 24 +
javascript/duktape/HTMLHTMLElement.bnd | 14 +
javascript/duktape/HTMLHeadingElement.bnd | 14 +
javascript/duktape/HTMLIFrameElement.bnd | 41 +
javascript/duktape/HTMLImageElement.bnd | 47 +
javascript/duktape/HTMLInputElement.bnd | 64 +
javascript/duktape/HTMLLIElement.bnd | 17 +
javascript/duktape/HTMLLabelElement.bnd | 14 +
javascript/duktape/HTMLLegendElement.bnd | 14 +
javascript/duktape/HTMLLinkElement.bnd | 35 +
javascript/duktape/HTMLMapElement.bnd | 14 +
javascript/duktape/HTMLMarqueeElement.bnd | 11 +
javascript/duktape/HTMLMenuElement.bnd | 14 +
javascript/duktape/HTMLMetaElement.bnd | 23 +
javascript/duktape/HTMLOListElement.bnd | 18 +
javascript/duktape/HTMLObjectElement.bnd | 54 +
javascript/duktape/HTMLOptionElement.bnd | 28 +
javascript/duktape/HTMLParagraphElement.bnd | 14 +
javascript/duktape/HTMLParamElement.bnd | 23 +
javascript/duktape/HTMLPreElement.bnd | 15 +
javascript/duktape/HTMLQuoteElement.bnd | 14 +
javascript/duktape/HTMLScriptElement.bnd | 32 +
javascript/duktape/HTMLSelectElement.bnd | 26 +
javascript/duktape/HTMLStyleElement.bnd | 17 +
javascript/duktape/HTMLTableCaptionElement.bnd | 14 +
javascript/duktape/HTMLTableCellElement.bnd | 46 +
javascript/duktape/HTMLTableColElement.bnd | 26 +
javascript/duktape/HTMLTableElement.bnd | 38 +
javascript/duktape/HTMLTableRowElement.bnd | 30 +
javascript/duktape/HTMLTableSectionElement.bnd | 23 +
javascript/duktape/HTMLTextAreaElement.bnd | 30 +
javascript/duktape/HTMLTitleElement.bnd | 14 +
javascript/duktape/Location.bnd | 353 +
javascript/duktape/Makefile | 40 +
javascript/duktape/Navigator.bnd | 87 +
javascript/duktape/Node.bnd | 38 +-
javascript/duktape/NodeList.bnd | 6 +-
javascript/duktape/Window.bnd | 75 +-
javascript/duktape/duk_config.h | 164 +-
javascript/duktape/duk_custom.h | 2 +
javascript/{ => duktape}/dukky.c | 401 +-
javascript/{ => duktape}/dukky.h | 7 +-
javascript/duktape/duktape.c |10608 ++++++++++++++++----
javascript/duktape/duktape.h | 77 +-
javascript/duktape/netsurf.bnd | 220 +-
javascript/js.h | 20 +
javascript/{ => jsapi}/Makefile | 46 +-
javascript/{ => jsapi}/jsapi.c | 0
javascript/{ => jsapi}/jsapi.h | 0
javascript/none/Makefile | 9 +
javascript/{ => none}/none.c | 8 +
render/box_construct.c | 6 +
render/form.h | 1 +
render/html.c | 49 +
render/html_interaction.c | 37 +-
render/html_internal.h | 8 +
render/html_script.c | 9 +-
render/layout.c | 44 +-
resources/FatMessages | 298 +-
riscos/bitmap.c | 6 +
riscos/buffer.c | 116 +-
riscos/filetype.c | 3 +-
riscos/gui.c | 5 +-
riscos/gui/url_bar.c | 2 +-
riscos/templates/nl | 2 +-
riscos/window.c | 14 +-
test/js/dom-element-attribute.html | 26 +
test/js/dom-element-firstElementChild.html | 2 +
test/js/dom-element-lastElementChild.html | 2 +
test/js/dom-element-next_prev_ElementSibling.html | 3 +
test/js/dom-element-reflection.html | 21 +
test/js/dom-html-div-element.html | 22 +
test/js/dom-node-parentNode.html | 23 +
test/js/index.html | 30 +-
test/js/location-assign.html | 13 +
test/js/location-href.html | 13 +
test/js/location-putforwards.html | 13 +
test/js/location-replace.html | 13 +
...ent-enumerate.html => navigator-enumerate.html} | 8 +-
utils/nsoption.c | 19 +-
utils/nsurl.c | 60 +
utils/nsurl.h | 18 +
utils/utils.h | 2 +
155 files changed, 17139 insertions(+), 4821 deletions(-)
create mode 100644 Docs/UnimplementedJavascript.txt
delete mode 100644 amiga/context_menu.c
create mode 100644 amiga/ctxmenu.c
create mode 100644 amiga/ctxmenu.h
mode change 100755 => 100644 amiga/gui.h
create mode 100644 amiga/selectmenu.c
rename amiga/{context_menu.h => selectmenu.h} (74%)
delete mode 120000 beos/res/messages
create mode 100644 javascript/WebIDL/cssom.idl
create mode 100644 javascript/WebIDL/dom-parsing.idl
create mode 100644 javascript/duktape/Event.bnd
create mode 100644 javascript/duktape/HTMLAnchorElement.bnd
create mode 100644 javascript/duktape/HTMLAppletElement.bnd
create mode 100644 javascript/duktape/HTMLAreaElement.bnd
create mode 100644 javascript/duktape/HTMLBRElement.bnd
create mode 100644 javascript/duktape/HTMLBaseElement.bnd
create mode 100644 javascript/duktape/HTMLBodyElement.bnd
create mode 100644 javascript/duktape/HTMLButtonElement.bnd
create mode 100644 javascript/duktape/HTMLDivElement.bnd
create mode 100644 javascript/duktape/HTMLElement.bnd
create mode 100644 javascript/duktape/HTMLFontElement.bnd
create mode 100644 javascript/duktape/HTMLFormElement.bnd
create mode 100644 javascript/duktape/HTMLFrameElement.bnd
create mode 100644 javascript/duktape/HTMLFrameSetElement.bnd
create mode 100644 javascript/duktape/HTMLHRElement.bnd
create mode 100644 javascript/duktape/HTMLHTMLElement.bnd
create mode 100644 javascript/duktape/HTMLHeadingElement.bnd
create mode 100644 javascript/duktape/HTMLIFrameElement.bnd
create mode 100644 javascript/duktape/HTMLImageElement.bnd
create mode 100644 javascript/duktape/HTMLInputElement.bnd
create mode 100644 javascript/duktape/HTMLLIElement.bnd
create mode 100644 javascript/duktape/HTMLLabelElement.bnd
create mode 100644 javascript/duktape/HTMLLegendElement.bnd
create mode 100644 javascript/duktape/HTMLLinkElement.bnd
create mode 100644 javascript/duktape/HTMLMapElement.bnd
create mode 100644 javascript/duktape/HTMLMarqueeElement.bnd
create mode 100644 javascript/duktape/HTMLMenuElement.bnd
create mode 100644 javascript/duktape/HTMLMetaElement.bnd
create mode 100644 javascript/duktape/HTMLOListElement.bnd
create mode 100644 javascript/duktape/HTMLObjectElement.bnd
create mode 100644 javascript/duktape/HTMLOptionElement.bnd
create mode 100644 javascript/duktape/HTMLParagraphElement.bnd
create mode 100644 javascript/duktape/HTMLParamElement.bnd
create mode 100644 javascript/duktape/HTMLPreElement.bnd
create mode 100644 javascript/duktape/HTMLQuoteElement.bnd
create mode 100644 javascript/duktape/HTMLScriptElement.bnd
create mode 100644 javascript/duktape/HTMLSelectElement.bnd
create mode 100644 javascript/duktape/HTMLStyleElement.bnd
create mode 100644 javascript/duktape/HTMLTableCaptionElement.bnd
create mode 100644 javascript/duktape/HTMLTableCellElement.bnd
create mode 100644 javascript/duktape/HTMLTableColElement.bnd
create mode 100644 javascript/duktape/HTMLTableElement.bnd
create mode 100644 javascript/duktape/HTMLTableRowElement.bnd
create mode 100644 javascript/duktape/HTMLTableSectionElement.bnd
create mode 100644 javascript/duktape/HTMLTextAreaElement.bnd
create mode 100644 javascript/duktape/HTMLTitleElement.bnd
create mode 100644 javascript/duktape/Location.bnd
create mode 100644 javascript/duktape/Makefile
create mode 100644 javascript/duktape/Navigator.bnd
rename javascript/{ => duktape}/dukky.c (52%)
rename javascript/{ => duktape}/dukky.h (82%)
copy javascript/{ => jsapi}/Makefile (58%)
rename javascript/{ => jsapi}/jsapi.c (100%)
rename javascript/{ => jsapi}/jsapi.h (100%)
create mode 100644 javascript/none/Makefile
rename javascript/{ => none}/none.c (91%)
create mode 100644 test/js/dom-element-attribute.html
create mode 100644 test/js/dom-element-reflection.html
create mode 100644 test/js/dom-html-div-element.html
create mode 100644 test/js/dom-node-parentNode.html
create mode 100644 test/js/location-assign.html
create mode 100644 test/js/location-href.html
create mode 100644 test/js/location-putforwards.html
create mode 100644 test/js/location-replace.html
copy test/js/{dom-document-enumerate.html => navigator-enumerate.html} (78%)
diff --git a/!NetSurf/Resources/ca-bundle b/!NetSurf/Resources/ca-bundle
index 67f696a..759a4d6 100644
--- a/!NetSurf/Resources/ca-bundle
+++ b/!NetSurf/Resources/ca-bundle
@@ -1,75 +1,23 @@
##
-## ca-bundle.crt -- Bundle of CA Root Certificates
+## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Tue Jan 28 09:38:07 2014
+## Certificate data from Mozilla as of: Mon Apr 27 08:58:04 2015
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
## file (certdata.txt). This file can be found in the mozilla source tree:
-##
http://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/built...
+##
http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/...
##
## It contains the certificates in PEM format and therefore
## can be directly used with curl / libcurl / php_curl, or with
## an Apache+mod_ssl webserver for SSL client authentication.
## Just configure this file as the SSLCACertificateFile.
##
+## Conversion done with mk-ca-bundle.pl version 1.25.
+## SHA1: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c
+##
-GTE CyberTrust Global Root
-==========================
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
-Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
-A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
-MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
-Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
-IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
-sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
-HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
-AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
-M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
-NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
-
-Thawte Server CA
-================
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
-dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
-AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
-b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
-BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
-c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
-A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
-/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
-1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
-MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
-GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
-GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
-
-Thawte Premium Server CA
-========================
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
-dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
-AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
-ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
-AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
-VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
-aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
-cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
-aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
-Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
-qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
-SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
-8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
-UCemDaYj+bvLpgcUQg==
------END CERTIFICATE-----
-
Equifax Secure CA
=================
-----BEGIN CERTIFICATE-----
@@ -90,41 +38,6 @@
BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
70+sB3c4
-----END CERTIFICATE-----
-Verisign Class 3 Public Primary Certification Authority
-=======================================================
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
-XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
-f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
-hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
-TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
-WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
-Tqj/ZA1k
------END CERTIFICATE-----
-
-Verisign Class 3 Public Primary Certification Authority - G2
-============================================================
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
-FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
-lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
-MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
-1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
-Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
------END CERTIFICATE-----
-
GlobalSign Root CA
==================
-----BEGIN CERTIFICATE-----
@@ -168,63 +81,6 @@
BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
-ValiCert Class 1 VA
-===================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
-MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
-GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
-DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
-lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
-icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
-Orf1LXLI
------END CERTIFICATE-----
-
-ValiCert Class 2 VA
-===================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
-MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
-CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
-ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
-SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
-UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
-W9ViH0Pd
------END CERTIFICATE-----
-
-RSA Root Certificate 1
-======================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
-MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td
-3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H
-BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs
-3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF
-V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r
-on+jjBXu
------END CERTIFICATE-----
-
Verisign Class 3 Public Primary Certification Authority - G3
============================================================
-----BEGIN CERTIFICATE-----
@@ -273,33 +129,6 @@
RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
-----END CERTIFICATE-----
-Entrust.net Secure Server CA
-============================
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV
-BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg
-cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl
-ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG
-A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi
-eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p
-dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ
-aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5
-gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw
-ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw
-CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l
-dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
-bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
-dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw
-NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow
-HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
-BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN
-Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9
-n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
-
Entrust.net Premium 2048 Secure Server CA
=========================================
-----BEGIN CERTIFICATE-----
@@ -345,40 +174,6 @@
Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
-Equifax Secure Global eBusiness CA
-==================================
------BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
-bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
-HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
-b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
-PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
-qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
-hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
-BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
-MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
-I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
-NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
------END CERTIFICATE-----
-
-Equifax Secure eBusiness CA 1
-=============================
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
-LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
-ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
-IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
-1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
-IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
-MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
-Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
-AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
-lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
-KpYrtWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
-
AddTrust Low-Value Services Root
================================
-----BEGIN CERTIFICATE-----
@@ -624,59 +419,6 @@
gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
-America Online Root Certification Authority 1
-=============================================
------BEGIN CERTIFICATE-----
-MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
-A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
-T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
-v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
-DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
-sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
-8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
-AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
-o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
-GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
-VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
-3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
-Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
-sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
------END CERTIFICATE-----
-
-America Online Root Certification Authority 2
-=============================================
------BEGIN CERTIFICATE-----
-MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG
-A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
-T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en
-fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8
-f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO
-qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN
-RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0
-gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn
-6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid
-FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6
-Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj
-B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op
-aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
-AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY
-T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p
-+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg
-JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy
-zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO
-ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh
-1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf
-GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff
-Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP
-cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
------END CERTIFICATE-----
-
Visa eCommerce Root
===================
-----BEGIN CERTIFICATE-----
@@ -953,30 +695,6 @@
nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
-----END CERTIFICATE-----
-TDC Internet Root CA
-====================
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE
-ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx
-NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu
-ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j
-xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL
-znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc
-5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6
-otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI
-AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM
-VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM
-MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC
-AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe
-UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G
-CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
-gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
-2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb
-O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU
-Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
------END CERTIFICATE-----
-
UTN DATACorp SGC Root CA
========================
-----BEGIN CERTIFICATE-----
@@ -1117,64 +835,6 @@
KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
8CgHrTwXZoi1/baI
-----END CERTIFICATE-----
-NetLock Business (Class B) Root
-===============================
------BEGIN CERTIFICATE-----
-MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
-CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
-BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg
-VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD
-VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv
-bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg
-VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S
-o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr
-1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
-HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ
-RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh
-dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0
-ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv
-c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg
-YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
-c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz
-Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA
-bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl
-IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2
-YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj
-cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM
-43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR
-stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI
------END CERTIFICATE-----
-
-NetLock Express (Class C) Root
-==============================
------BEGIN CERTIFICATE-----
-MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT
-CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
-BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD
-KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ
-BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
-dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j
-ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB
-jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z
-W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63
-euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw
-DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN
-RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn
-YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB
-IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i
-aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0
-ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
-ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo
-dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y
-emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k
-IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ
-UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg
-YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2
-xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW
-gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A==
------END CERTIFICATE-----
-
XRamp Global CA Root
====================
-----BEGIN CERTIFICATE-----
@@ -1318,31 +978,6 @@
CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
-----END CERTIFICATE-----
-Firmaprofesional Root CA
-========================
------BEGIN CERTIFICATE-----
-MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
-GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
-Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
-ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
-MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
-OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
-ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
-j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
-lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
-3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
-NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
-KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
-AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
-ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
-u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
-wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
-7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
-VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
------END CERTIFICATE-----
-
Swisscom Root CA 1
==================
-----BEGIN CERTIFICATE-----
@@ -1954,40 +1589,6 @@
PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
-AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
-======================================
------BEGIN CERTIFICATE-----
-MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT
-AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg
-LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w
-HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+
-U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh
-IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B
-AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN
-yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU
-2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3
-4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP
-2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm
-8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf
-HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa
-Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK
-5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b
-czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g
-ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF
-BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug
-cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf
-AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX
-EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v
-/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3
-MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4
-3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk
-eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f
-/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h
-RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU
-Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==
------END CERTIFICATE-----
-
TC TrustCenter Class 2 CA II
============================
-----BEGIN CERTIFICATE-----
@@ -2015,33 +1616,6 @@
JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
vQ==
-----END CERTIFICATE-----
-TC TrustCenter Class 3 CA II
-============================
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
-IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
-MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
-c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
-AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
-yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
-6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
-uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
-2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
-7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
-Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
-cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
-SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
-O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
-yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
-IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
-092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
-5A==
------END CERTIFICATE-----
-
TC TrustCenter Universal CA I
=============================
-----BEGIN CERTIFICATE-----
@@ -2635,22 +2209,6 @@
MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
-----END CERTIFICATE-----
-Verisign Class 3 Public Primary Certification Authority
-=======================================================
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
-XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
-f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
-hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
-CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
-bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
-D/xwzoiQ
------END CERTIFICATE-----
-
Microsec e-Szigno Root CA 2009
==============================
-----BEGIN CERTIFICATE-----
@@ -2675,28 +2233,6 @@
yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
LXpUq3DDfSJlgnCW
-----END CERTIFICATE-----
-E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi
-===================================================
------BEGIN CERTIFICATE-----
-MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
-EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz
-ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3
-MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0
-cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u
-aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY
-8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y
-jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI
-JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk
-9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD
-AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG
-SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d
-F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq
-D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4
-Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
-fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
------END CERTIFICATE-----
-
GlobalSign Root CA - R3
=======================
-----BEGIN CERTIFICATE-----
@@ -3783,3 +3319,670 @@
i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
-----END CERTIFICATE-----
+
+TeliaSonera Root CA v1
+======================
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
+CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
+MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
+VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
+6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
+3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
+B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
+Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
+oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
+F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
+oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
+gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
+TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
+AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
+DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
+zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
+pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
+G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
+c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
+JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
+qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
+Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
+WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+
+E-Tugra Certification Authority
+===============================
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
+DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
+ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
+NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
+QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
+cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
+DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
+hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
+CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
+ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
+BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
+E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
+rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
+jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
+dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
+/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
+MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
+kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
+XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
+VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
+a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
+dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
+KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
+Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
+8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
+C7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+
+T-TeleSec GlobalRoot Class 2
+============================
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
+IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
+cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
+MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
+dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
+ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
+SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
+vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
+2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
+WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
+YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
+r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
+vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
+3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
+-----END CERTIFICATE-----
+
+Atos TrustedRoot 2011
+=====================
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
+cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
+MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
+A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
+hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
+54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
+HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
+z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
+l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
+bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
+k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
+TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
+61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
+3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 1 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE
+PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm
+PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6
+Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
+ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l
+g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV
+7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX
+9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f
+iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg
+t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI
+hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3
+GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct
+Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP
++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh
+3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa
+wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6
+O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0
+FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV
+hMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 2 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh
+ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY
+NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
+oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o
+MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l
+V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo
+L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ
+sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD
+6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh
+lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI
+hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K
+pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9
+x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
+dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X
+U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw
+mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD
+zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN
+JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr
+O3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 3 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286
+IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
+Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe
+6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
+I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U
+VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7
+5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi
+Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM
+dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
+rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
+hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS
+t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ
+TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du
+DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib
+Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD
+hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX
+0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW
+dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2
+PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+
+DigiCert Assured ID Root G2
+===========================
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
+IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
+MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
+ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
+35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
+bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
+VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
+YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
+lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
+w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
+0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
+d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
+hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
+jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+
+DigiCert Assured ID Root G3
+===========================
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
+VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
+MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
+BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
+RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
+KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
+UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
+YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
+1vUhZscv6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+
+DigiCert Global Root G2
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
+HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
+MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
+dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
+kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
+3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
+BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
+UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
+5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
+F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
+WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
+QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
+iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+
+DigiCert Global Root G3
+=======================
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
+VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
+MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
+aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
+AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
+YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
+Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
+3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
+VOKa5Vt8sycX
+-----END CERTIFICATE-----
+
+DigiCert Trusted Root G4
+========================
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
+HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
+MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
+pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o
+k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
+vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
+QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6
+MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm
+mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7
+f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH
+dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8
+oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
+ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
+yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy
+7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah
+ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN
+5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb
+/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa
+5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK
+G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP
+82Z+
+-----END CERTIFICATE-----
+
+WoSign
+======
+-----BEGIN CERTIFICATE-----
+MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g
+QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ
+BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO
+CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX
+2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5
+KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR
++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez
+EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk
+lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2
+8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY
+yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C
+AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R
+8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
+LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq
+T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj
+y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC
+2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes
+5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/
+EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh
+mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx
+kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi
+kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w==
+-----END CERTIFICATE-----
+
+WoSign China
+============
+-----BEGIN CERTIFICATE-----
+MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv
+geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD
+VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k
+8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5
+uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85
+dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5
+Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy
+b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc
+76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m
++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6
+yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX
+GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA
+A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
+yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY
+r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115
+j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A
+kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97
+qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y
+jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB
+ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv
+T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO
+kI26oQ==
+-----END CERTIFICATE-----
+
+COMODO RSA Certification Authority
+==================================
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
+BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
+A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
+R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
+ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
+dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
+FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
+5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
+x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
+2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
+OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
+sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
+GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
+WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
+rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
+tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
+sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
+pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
+zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
+ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
+7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
+LaZRfyHBNVOFBkpdn627G190
+-----END CERTIFICATE-----
+
+USERTrust RSA Certification Authority
+=====================================
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
+BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
+ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
+BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
+ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
+0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
+Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
+RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
+/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
+Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
+lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
+yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
+eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
+FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
+7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
+Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
+8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
+FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
+yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
+J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
+sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
+Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+
+USERTrust ECC Certification Authority
+=====================================
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
+0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
+nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
+HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
+HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
+9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+
+GlobalSign ECC Root CA - R4
+===========================
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
+OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
+AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
+MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
+JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
+-----END CERTIFICATE-----
+
+GlobalSign ECC Root CA - R5
+===========================
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
+SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
+h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
+uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
+yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+
+Staat der Nederlanden Root CA - G3
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
+CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
+Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC
+TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
+ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y
+olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t
+x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy
+EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K
+Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur
+mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5
+1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp
+07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo
+FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE
+41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu
+yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq
+KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1
+v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA
+8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b
+8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r
+mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq
+1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI
+JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV
+tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=
+-----END CERTIFICATE-----
+
+Staat der Nederlanden EV Root CA
+================================
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE
+CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
+RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M
+MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl
+cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk
+SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW
+O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r
+0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8
+Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV
+XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr
+08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV
+0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd
+74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
+fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa
+ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu
+c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
+5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN
+b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN
+f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi
+5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4
+WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK
+DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy
+eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
+-----END CERTIFICATE-----
+
+IdenTrust Commercial Root CA 1
+==============================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG
+EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS
+b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES
+MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
+IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld
+hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/
+mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi
+1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C
+XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
+3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy
+NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV
+WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg
+xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix
+uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
+hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg
+ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
+ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV
+YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX
+feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro
+kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe
+2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz
+Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R
+cGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+
+IdenTrust Public Sector Root CA 1
+=================================
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG
+EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv
+ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV
+UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS
+b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy
+P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6
+Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI
+rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf
+qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS
+mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn
+ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh
+LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v
+iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL
+4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B
+Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw
+DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A
+mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt
+GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt
+m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx
+NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4
+Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI
+ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC
+ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
+3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+
+Entrust Root Certification Authority - G2
+=========================================
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
+BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
+bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
+b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
+HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
+DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
+OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
+/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
+HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
+s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
+TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
+AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
+0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
+iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
+nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
+e4pIb4tF9g==
+-----END CERTIFICATE-----
+
+Entrust Root Certification Authority - EC1
+==========================================
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
+YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
+FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
+LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
+dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
+IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
+AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
+9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
+vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
+kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+
+CFCA EV ROOT
+============
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE
+CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
+IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
+MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD
+DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV
+BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD
+7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN
+uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW
+ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7
+xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f
+py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K
+gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol
+hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ
+tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf
+BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
+/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q
+ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua
+4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG
+E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX
+BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn
+aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy
+PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
+kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
+ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
diff --git a/Docs/BUILDING-BeOS b/Docs/BUILDING-BeOS
index 8d33a68..8642861 100644
--- a/Docs/BUILDING-BeOS
+++ b/Docs/BUILDING-BeOS
@@ -5,18 +5,23 @@
This document provides instructions for building the BeOS and Haiku version
of NetSurf and provides guidance on obtaining NetSurf's build dependencies.
- BeOS NetSurf has been tested on Zeta only for now. There are still some
+ BeOS NetSurf has been tested on Zeta and Haiku only for now. There are still some
issues to sort out for other BeOS versions.
+ Quick Start
+=============
- There are still pending fixes against SVN before it can be build from BeOS
- or Haiku.
+ See the QUICK-START document, which provides a simple environment with
+ which you can fetch, build and install NetSurf and its dependencies.
+ The QUICK-START is the recommended way to build NetSurf for Haiku. BeOS needs too much
manual
+ hacking to be built this way.
- Building and executing NetSurf
+
+ Manual building
================================
- To build NetSurf on a BeOS or Haiku, provided you have the relevant
+ To build NetSurf on a BeOS, provided you have the relevant
build dependencies installed, simply run:
$ make
@@ -38,8 +43,19 @@
---------------------------------
The NetSurf project has developed several libraries which are required by
- the browser. To fetch each of these libraries, run the appropriate commands
- from the Docs/LIBRARIES file.
+ the browser. These are:
+
+ BuildSystem -- Shared build system, needed to build the other libraries
+ LibParserUtils -- Parser building utility functions
+ LibWapcaplet -- String internment
+ Hubbub -- HTML5 compliant HTML parser
+ LibCSS -- CSS parser and selection engine
+ LibNSGIF -- GIF format image decoder
+ LibNSBMP -- BMP and ICO format image decoder
+ LibROSprite -- RISC OS Sprite format image decoder
+
+ To fetch each of these libraries, run the appropriate commands from the
+ Docs/LIBRARIES file, from within your workspace directory.
To build and install these libraries, simply enter each of their directories
and run:
@@ -57,6 +73,13 @@
TODO: add some more here.
+ Additional requirements for BeOS
+==================================
+
+ On Haiku, other libraries and tools are either shipped with the system or available
through the
+ package repositories. For BeOS based systems, you will need to install and update all
the
+ required tools, as described below.
+
rc
----
@@ -121,7 +144,3 @@
NetSurf might build on BeOS R5 but probably won't work on anything else than
BONE.
-
- This will pull in loads of things, like all the GTK dev libraries, the PNG
- and JPEG libraries, colour management libraries, zlib, OpenSSL etc that
- NetSurf also depends on.
diff --git a/Docs/Doxyfile b/Docs/Doxyfile
index c2a8bba..c8497ad 100644
--- a/Docs/Doxyfile
+++ b/Docs/Doxyfile
@@ -681,7 +681,8 @@ INPUT = windows \
javascript/jsapi \
utils \
utils/http \
- image
+ image \
+ Docs/UnimplementedJavascript.txt
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/Docs/UnimplementedJavascript.txt b/Docs/UnimplementedJavascript.txt
new file mode 100644
index 0000000..cb50699
--- /dev/null
+++ b/Docs/UnimplementedJavascript.txt
@@ -0,0 +1,1802 @@
+/** \page unimplemented Unimplemented javascript bindings
+This is a list of all the binding methods, getters and setters without an implementation
in a binding.
+
+method ApplicationCache::abort();\n
+getter ApplicationCache::oncached(user);\n
+setter ApplicationCache::oncached(user);\n
+getter ApplicationCache::onchecking(user);\n
+setter ApplicationCache::onchecking(user);\n
+getter ApplicationCache::ondownloading(user);\n
+setter ApplicationCache::ondownloading(user);\n
+getter ApplicationCache::onerror(user);\n
+setter ApplicationCache::onerror(user);\n
+getter ApplicationCache::onnoupdate(user);\n
+setter ApplicationCache::onnoupdate(user);\n
+getter ApplicationCache::onobsolete(user);\n
+setter ApplicationCache::onobsolete(user);\n
+getter ApplicationCache::onprogress(user);\n
+setter ApplicationCache::onprogress(user);\n
+getter ApplicationCache::onupdateready(user);\n
+setter ApplicationCache::onupdateready(user);\n
+getter ApplicationCache::status(unsigned short);\n
+method ApplicationCache::swapCache();\n
+method ApplicationCache::update();\n
+getter Attr::localName(string);\n
+getter Attr::namespaceURI(string);\n
+getter Attr::name(string);\n
+getter Attr::nodeValue(string);\n
+setter Attr::nodeValue(string);\n
+getter Attr::ownerElement(user);\n
+getter Attr::prefix(string);\n
+getter Attr::specified(boolean);\n
+getter Attr::textContent(string);\n
+setter Attr::textContent(string);\n
+getter Attr::value(string);\n
+setter Attr::value(string);\n
+getter AudioTrack::enabled(boolean);\n
+setter AudioTrack::enabled(boolean);\n
+getter AudioTrack::id(string);\n
+getter AudioTrack::kind(string);\n
+getter AudioTrack::label(string);\n
+getter AudioTrack::language(string);\n
+method AudioTrackList::getTrackById();\n
+getter AudioTrackList::length(unsigned long);\n
+getter AudioTrackList::onaddtrack(user);\n
+setter AudioTrackList::onaddtrack(user);\n
+getter AudioTrackList::onchange(user);\n
+setter AudioTrackList::onchange(user);\n
+getter AudioTrackList::onremovetrack(user);\n
+setter AudioTrackList::onremovetrack(user);\n
+getter AutocompleteErrorEvent::reason(user);\n
+getter BarProp::visible(boolean);\n
+getter BeforeUnloadEvent::returnValue(string);\n
+setter BeforeUnloadEvent::returnValue(string);\n
+method BroadcastChannel::close();\n
+getter BroadcastChannel::name(string);\n
+getter BroadcastChannel::onmessage(user);\n
+setter BroadcastChannel::onmessage(user);\n
+method BroadcastChannel::postMessage();\n
+method CanvasGradient::addColorStop();\n
+method CanvasPattern::setTransform();\n
+method CanvasProxy::setContext();\n
+method CanvasRenderingContext2D::addHitRegion();\n
+method CanvasRenderingContext2D::arc();\n
+method CanvasRenderingContext2D::arcTo();\n
+method CanvasRenderingContext2D::beginPath();\n
+method CanvasRenderingContext2D::bezierCurveTo();\n
+getter CanvasRenderingContext2D::canvas(user);\n
+method CanvasRenderingContext2D::clearHitRegions();\n
+method CanvasRenderingContext2D::clearRect();\n
+method CanvasRenderingContext2D::clip();\n
+method CanvasRenderingContext2D::closePath();\n
+method CanvasRenderingContext2D::commit();\n
+method CanvasRenderingContext2D::createImageData();\n
+method CanvasRenderingContext2D::createLinearGradient();\n
+method CanvasRenderingContext2D::createPattern();\n
+method CanvasRenderingContext2D::createRadialGradient();\n
+getter CanvasRenderingContext2D::currentTransform(user);\n
+setter CanvasRenderingContext2D::currentTransform(user);\n
+getter CanvasRenderingContext2D::direction(string);\n
+setter CanvasRenderingContext2D::direction(string);\n
+method CanvasRenderingContext2D::drawFocusIfNeeded();\n
+method CanvasRenderingContext2D::drawImage();\n
+method CanvasRenderingContext2D::ellipse();\n
+method CanvasRenderingContext2D::fill();\n
+method CanvasRenderingContext2D::fillRect();\n
+getter CanvasRenderingContext2D::fillStyle(multiple);\n
+setter CanvasRenderingContext2D::fillStyle(multiple);\n
+method CanvasRenderingContext2D::fillText();\n
+getter CanvasRenderingContext2D::font(string);\n
+setter CanvasRenderingContext2D::font(string);\n
+method CanvasRenderingContext2D::getImageData();\n
+method CanvasRenderingContext2D::getLineDash();\n
+getter CanvasRenderingContext2D::globalAlpha(double);\n
+setter CanvasRenderingContext2D::globalAlpha(double);\n
+getter CanvasRenderingContext2D::globalCompositeOperation(string);\n
+setter CanvasRenderingContext2D::globalCompositeOperation(string);\n
+getter CanvasRenderingContext2D::height(unsigned long);\n
+setter CanvasRenderingContext2D::height(unsigned long);\n
+getter CanvasRenderingContext2D::imageSmoothingEnabled(boolean);\n
+setter CanvasRenderingContext2D::imageSmoothingEnabled(boolean);\n
+getter CanvasRenderingContext2D::imageSmoothingQuality(user);\n
+setter CanvasRenderingContext2D::imageSmoothingQuality(user);\n
+method CanvasRenderingContext2D::isPointInPath();\n
+method CanvasRenderingContext2D::isPointInStroke();\n
+getter CanvasRenderingContext2D::lineCap(string);\n
+setter CanvasRenderingContext2D::lineCap(string);\n
+getter CanvasRenderingContext2D::lineDashOffset(double);\n
+setter CanvasRenderingContext2D::lineDashOffset(double);\n
+getter CanvasRenderingContext2D::lineJoin(string);\n
+setter CanvasRenderingContext2D::lineJoin(string);\n
+method CanvasRenderingContext2D::lineTo();\n
+getter CanvasRenderingContext2D::lineWidth(double);\n
+setter CanvasRenderingContext2D::lineWidth(double);\n
+method CanvasRenderingContext2D::measureText();\n
+getter CanvasRenderingContext2D::miterLimit(double);\n
+setter CanvasRenderingContext2D::miterLimit(double);\n
+method CanvasRenderingContext2D::moveTo();\n
+method CanvasRenderingContext2D::putImageData();\n
+method CanvasRenderingContext2D::quadraticCurveTo();\n
+method CanvasRenderingContext2D::rect();\n
+method CanvasRenderingContext2D::removeHitRegion();\n
+method CanvasRenderingContext2D::resetClip();\n
+method CanvasRenderingContext2D::resetTransform();\n
+method CanvasRenderingContext2D::restore();\n
+method CanvasRenderingContext2D::rotate();\n
+method CanvasRenderingContext2D::save();\n
+method CanvasRenderingContext2D::scale();\n
+method CanvasRenderingContext2D::scrollPathIntoView();\n
+method CanvasRenderingContext2D::setLineDash();\n
+method CanvasRenderingContext2D::setTransform();\n
+getter CanvasRenderingContext2D::shadowBlur(double);\n
+setter CanvasRenderingContext2D::shadowBlur(double);\n
+getter CanvasRenderingContext2D::shadowColor(string);\n
+setter CanvasRenderingContext2D::shadowColor(string);\n
+getter CanvasRenderingContext2D::shadowOffsetX(double);\n
+setter CanvasRenderingContext2D::shadowOffsetX(double);\n
+getter CanvasRenderingContext2D::shadowOffsetY(double);\n
+setter CanvasRenderingContext2D::shadowOffsetY(double);\n
+method CanvasRenderingContext2D::stroke();\n
+method CanvasRenderingContext2D::strokeRect();\n
+getter CanvasRenderingContext2D::strokeStyle(multiple);\n
+setter CanvasRenderingContext2D::strokeStyle(multiple);\n
+method CanvasRenderingContext2D::strokeText();\n
+getter CanvasRenderingContext2D::textAlign(string);\n
+setter CanvasRenderingContext2D::textAlign(string);\n
+getter CanvasRenderingContext2D::textBaseline(string);\n
+setter CanvasRenderingContext2D::textBaseline(string);\n
+method CanvasRenderingContext2D::transform();\n
+method CanvasRenderingContext2D::translate();\n
+getter CanvasRenderingContext2D::width(unsigned long);\n
+setter CanvasRenderingContext2D::width(unsigned long);\n
+method CharacterData::after();\n
+method CharacterData::appendData();\n
+method CharacterData::before();\n
+getter CharacterData::data(string);\n
+setter CharacterData::data(string);\n
+method CharacterData::deleteData();\n
+method CharacterData::insertData();\n
+getter CharacterData::length(unsigned long);\n
+getter CharacterData::nextElementSibling(user);\n
+getter CharacterData::previousElementSibling(user);\n
+method CharacterData::remove();\n
+method CharacterData::replaceData();\n
+method CharacterData::replaceWith();\n
+method CharacterData::substringData();\n
+getter CloseEvent::code(unsigned short);\n
+getter CloseEvent::reason(string);\n
+getter CloseEvent::wasClean(boolean);\n
+getter CompositionEvent::data(string);\n
+method CompositionEvent::initCompositionEvent();\n
+method CSS::escape();\n
+getter CSSGroupingRule::cssRules(user);\n
+method CSSGroupingRule::deleteRule();\n
+method CSSGroupingRule::insertRule();\n
+getter CSSImportRule::href(string);\n
+getter CSSImportRule::media(user);\n
+getter CSSImportRule::styleSheet(user);\n
+getter CSSMarginRule::name(string);\n
+getter CSSMarginRule::style(user);\n
+getter CSSMediaRule::media(user);\n
+getter CSSNamespaceRule::namespaceURI(string);\n
+getter CSSNamespaceRule::prefix(string);\n
+getter CSSPageRule::selectorText(string);\n
+setter CSSPageRule::selectorText(string);\n
+getter CSSPageRule::style(user);\n
+getter CSSRule::cssText(string);\n
+setter CSSRule::cssText(string);\n
+method CSSRuleList::item();\n
+getter CSSRuleList::length(unsigned long);\n
+getter CSSRule::parentRule(user);\n
+getter CSSRule::parentStyleSheet(user);\n
+getter CSSRule::type(unsigned short);\n
+getter CSSStyleDeclaration::cssFloat(string);\n
+setter CSSStyleDeclaration::cssFloat(string);\n
+getter CSSStyleDeclaration::cssText(string);\n
+setter CSSStyleDeclaration::cssText(string);\n
+getter CSSStyleDeclaration::dashed_attribute(string);\n
+setter CSSStyleDeclaration::dashed_attribute(string);\n
+method CSSStyleDeclaration::getPropertyPriority();\n
+method CSSStyleDeclaration::getPropertyValue();\n
+method CSSStyleDeclaration::item();\n
+getter CSSStyleDeclaration::length(unsigned long);\n
+getter CSSStyleDeclaration::parentRule(user);\n
+method CSSStyleDeclaration::removeProperty();\n
+method CSSStyleDeclaration::setProperty();\n
+method CSSStyleDeclaration::setPropertyPriority();\n
+method CSSStyleDeclaration::setPropertyValue();\n
+getter CSSStyleRule::selectorText(string);\n
+setter CSSStyleRule::selectorText(string);\n
+getter CSSStyleRule::style(user);\n
+getter CSSStyleSheet::cssRules(user);\n
+method CSSStyleSheet::deleteRule();\n
+method CSSStyleSheet::insertRule();\n
+getter CSSStyleSheet::ownerRule(user);\n
+getter CustomEvent::detail(any);\n
+method CustomEvent::initCustomEvent();\n
+method DataTransfer::clearData();\n
+getter DataTransfer::dropEffect(string);\n
+setter DataTransfer::dropEffect(string);\n
+getter DataTransfer::effectAllowed(string);\n
+setter DataTransfer::effectAllowed(string);\n
+getter DataTransfer::files(user);\n
+method DataTransfer::getData();\n
+method DataTransferItem::getAsFile();\n
+method DataTransferItem::getAsString();\n
+getter DataTransferItem::kind(string);\n
+method DataTransferItemList::add();\n
+method DataTransferItemList::clear();\n
+getter DataTransferItemList::length(unsigned long);\n
+method DataTransferItemList::remove();\n
+getter DataTransfer::items(user);\n
+getter DataTransferItem::type(string);\n
+method DataTransfer::setData();\n
+method DataTransfer::setDragImage();\n
+getter DataTransfer::types(string);\n
+getter DedicatedWorkerGlobalScope::onmessage(user);\n
+setter DedicatedWorkerGlobalScope::onmessage(user);\n
+method DedicatedWorkerGlobalScope::postMessage();\n
+getter Document::activeElement(user);\n
+method Document::adoptNode();\n
+getter Document::alinkColor(string);\n
+setter Document::alinkColor(string);\n
+getter Document::all(user);\n
+getter Document::anchors(user);\n
+method Document::append();\n
+getter Document::applets(user);\n
+getter Document::bgColor(string);\n
+setter Document::bgColor(string);\n
+setter Document::body(user);\n
+method Document::captureEvents();\n
+getter Document::characterSet(string);\n
+getter Document::childElementCount(unsigned long);\n
+getter Document::children(user);\n
+method Document::clear();\n
+method Document::close();\n
+getter Document::commands(user);\n
+getter Document::compatMode(string);\n
+getter Document::contentType(string);\n
+setter Document::cookie(string);\n
+method Document::createAttribute();\n
+method Document::createAttributeNS();\n
+method Document::createComment();\n
+method Document::createDocumentFragment();\n
+method Document::createElementNS();\n
+method Document::createEvent();\n
+method Document::createNodeIterator();\n
+method Document::createProcessingInstruction();\n
+method Document::createRange();\n
+method Document::createTreeWalker();\n
+getter Document::cssElementMap(user);\n
+getter Document::currentScript(user);\n
+getter Document::defaultView(user);\n
+getter Document::designMode(string);\n
+setter Document::designMode(string);\n
+getter Document::dir(string);\n
+setter Document::dir(string);\n
+getter Document::doctype(user);\n
+getter Document::documentURI(string);\n
+getter Document::domain(string);\n
+setter Document::domain(string);\n
+getter Document::embeds(user);\n
+method Document::enableStyleSheetsForSet();\n
+method Document::execCommand();\n
+getter Document::fgColor(string);\n
+setter Document::fgColor(string);\n
+getter Document::firstElementChild(user);\n
+getter Document::forms(user);\n
+method DocumentFragment::append();\n
+getter DocumentFragment::childElementCount(unsigned long);\n
+getter DocumentFragment::children(user);\n
+getter DocumentFragment::firstElementChild(user);\n
+method DocumentFragment::getElementById();\n
+getter DocumentFragment::lastElementChild(user);\n
+method DocumentFragment::prepend();\n
+method DocumentFragment::query();\n
+method DocumentFragment::queryAll();\n
+method DocumentFragment::querySelector();\n
+method DocumentFragment::querySelectorAll();\n
+method Document::getElementsByClassName();\n
+method Document::getElementsByName();\n
+method Document::getElementsByTagNameNS();\n
+method Document::hasFocus();\n
+getter Document::images(user);\n
+getter Document::implementation(user);\n
+method Document::importNode();\n
+getter Document::inputEncoding(string);\n
+getter Document::lastElementChild(user);\n
+getter Document::lastModified(string);\n
+getter Document::lastStyleSheetSet(string);\n
+getter Document::linkColor(string);\n
+setter Document::linkColor(string);\n
+getter Document::links(user);\n
+getter Document::onerror(user);\n
+setter Document::onerror(user);\n
+method Document::open();\n
+getter Document::origin(string);\n
+getter Document::plugins(user);\n
+getter Document::preferredStyleSheetSet(string);\n
+method Document::prepend();\n
+method Document::query();\n
+method Document::queryAll();\n
+method Document::queryCommandEnabled();\n
+method Document::queryCommandIndeterm();\n
+method Document::queryCommandState();\n
+method Document::queryCommandSupported();\n
+method Document::queryCommandValue();\n
+method Document::querySelector();\n
+method Document::querySelectorAll();\n
+getter Document::readyState(user);\n
+getter Document::referrer(string);\n
+method Document::releaseEvents();\n
+getter Document::scripts(user);\n
+getter Document::selectedStyleSheetSet(string);\n
+setter Document::selectedStyleSheetSet(string);\n
+getter Document::styleSheetSets(string);\n
+getter Document::styleSheets(user);\n
+getter Document::title(string);\n
+setter Document::title(string);\n
+method DocumentType::after();\n
+method DocumentType::before();\n
+getter DocumentType::name(string);\n
+getter DocumentType::publicId(string);\n
+method DocumentType::remove();\n
+method DocumentType::replaceWith();\n
+getter DocumentType::systemId(string);\n
+getter Document::URL(string);\n
+getter Document::vlinkColor(string);\n
+setter Document::vlinkColor(string);\n
+method DOMImplementation::createDocument();\n
+method DOMImplementation::createDocumentType();\n
+method DOMImplementation::createHTMLDocument();\n
+method DOMImplementation::hasFeature();\n
+method DOMParser::parseFromString();\n
+getter DOMSettableTokenList::value(string);\n
+setter DOMSettableTokenList::value(string);\n
+method DOMTokenList::add();\n
+method DOMTokenList::contains();\n
+method DOMTokenList::item();\n
+getter DOMTokenList::length(unsigned long);\n
+method DOMTokenList::remove();\n
+method DOMTokenList::toggle();\n
+getter DragEvent::dataTransfer(user);\n
+getter DrawingStyle::direction(string);\n
+setter DrawingStyle::direction(string);\n
+getter DrawingStyle::font(string);\n
+setter DrawingStyle::font(string);\n
+method DrawingStyle::getLineDash();\n
+getter DrawingStyle::lineCap(string);\n
+setter DrawingStyle::lineCap(string);\n
+getter DrawingStyle::lineDashOffset(double);\n
+setter DrawingStyle::lineDashOffset(double);\n
+getter DrawingStyle::lineJoin(string);\n
+setter DrawingStyle::lineJoin(string);\n
+getter DrawingStyle::lineWidth(double);\n
+setter DrawingStyle::lineWidth(double);\n
+getter DrawingStyle::miterLimit(double);\n
+setter DrawingStyle::miterLimit(double);\n
+method DrawingStyle::setLineDash();\n
+getter DrawingStyle::textAlign(string);\n
+setter DrawingStyle::textAlign(string);\n
+getter DrawingStyle::textBaseline(string);\n
+setter DrawingStyle::textBaseline(string);\n
+method Element::after();\n
+method Element::append();\n
+getter Element::attributes(user);\n
+method Element::before();\n
+getter Element::cascadedStyle(user);\n
+getter Element::children(user);\n
+getter Element::classList(user);\n
+method Element::closest();\n
+getter Element::defaultStyle(user);\n
+method Element::getAttributeNode();\n
+method Element::getAttributeNodeNS();\n
+method Element::getAttributeNS();\n
+method Element::getElementsByClassName();\n
+method Element::getElementsByTagNameNS();\n
+method Element::hasAttributeNS();\n
+method Element::hasAttributes();\n
+getter Element::innerHTML(string);\n
+setter Element::innerHTML(string);\n
+method Element::insertAdjacentHTML();\n
+getter Element::localName(string);\n
+method Element::matches();\n
+getter Element::namespaceURI(string);\n
+getter Element::outerHTML(string);\n
+setter Element::outerHTML(string);\n
+getter Element::prefix(string);\n
+method Element::prepend();\n
+method Element::pseudo();\n
+method Element::query();\n
+method Element::queryAll();\n
+method Element::querySelector();\n
+method Element::querySelectorAll();\n
+getter Element::rawComputedStyle(user);\n
+method Element::remove();\n
+method Element::removeAttributeNode();\n
+method Element::removeAttributeNS();\n
+method Element::replaceWith();\n
+method Element::setAttributeNode();\n
+method Element::setAttributeNodeNS();\n
+method Element::setAttributeNS();\n
+getter Element::tagName(string);\n
+getter Element::usedStyle(user);\n
+getter ErrorEvent::colno(unsigned long);\n
+getter ErrorEvent::error(any);\n
+getter ErrorEvent::filename(string);\n
+getter ErrorEvent::lineno(unsigned long);\n
+getter ErrorEvent::message(string);\n
+method Event::initEvent();\n
+getter Event::isTrusted(boolean);\n
+method EventListener::handleEvent();\n
+method EventSource::close();\n
+getter EventSource::onerror(user);\n
+setter EventSource::onerror(user);\n
+getter EventSource::onmessage(user);\n
+setter EventSource::onmessage(user);\n
+getter EventSource::onopen(user);\n
+setter EventSource::onopen(user);\n
+getter EventSource::readyState(unsigned short);\n
+getter EventSource::url(string);\n
+getter EventSource::withCredentials(boolean);\n
+method EventTarget::addEventListener();\n
+method EventTarget::dispatchEvent();\n
+method EventTarget::removeEventListener();\n
+getter Event::timeStamp(user);\n
+method External::AddSearchProvider();\n
+method External::IsSearchProviderInstalled();\n
+method FocusEvent::initFocusEvent();\n
+getter FocusEvent::relatedTarget(user);\n
+getter HashChangeEvent::newURL(string);\n
+getter HashChangeEvent::oldURL(string);\n
+method History::back();\n
+method History::forward();\n
+method History::go();\n
+getter History::length(unsigned long);\n
+method History::pushState();\n
+method History::replaceState();\n
+getter History::state(any);\n
+method HTMLAllCollection::item();\n
+getter HTMLAllCollection::length(unsigned long);\n
+method HTMLAllCollection::namedItem();\n
+getter HTMLAnchorElement::download(string);\n
+setter HTMLAnchorElement::download(string);\n
+getter HTMLAnchorElement::hash(user);\n
+setter HTMLAnchorElement::hash(user);\n
+getter HTMLAnchorElement::hostname(user);\n
+setter HTMLAnchorElement::hostname(user);\n
+getter HTMLAnchorElement::host(user);\n
+setter HTMLAnchorElement::host(user);\n
+getter HTMLAnchorElement::href(user);\n
+setter HTMLAnchorElement::href(user);\n
+getter HTMLAnchorElement::origin(user);\n
+getter HTMLAnchorElement::password(user);\n
+setter HTMLAnchorElement::password(user);\n
+getter HTMLAnchorElement::pathname(user);\n
+setter HTMLAnchorElement::pathname(user);\n
+getter HTMLAnchorElement::ping(user);\n
+getter HTMLAnchorElement::port(user);\n
+setter HTMLAnchorElement::port(user);\n
+getter HTMLAnchorElement::protocol(user);\n
+setter HTMLAnchorElement::protocol(user);\n
+getter HTMLAnchorElement::relList(user);\n
+getter HTMLAnchorElement::search(user);\n
+setter HTMLAnchorElement::search(user);\n
+getter HTMLAnchorElement::text(string);\n
+setter HTMLAnchorElement::text(string);\n
+getter HTMLAnchorElement::type(string);\n
+setter HTMLAnchorElement::type(string);\n
+getter HTMLAnchorElement::username(user);\n
+setter HTMLAnchorElement::username(user);\n
+getter HTMLAppletElement::hspace(unsigned long);\n
+setter HTMLAppletElement::hspace(unsigned long);\n
+getter HTMLAppletElement::vspace(unsigned long);\n
+setter HTMLAppletElement::vspace(unsigned long);\n
+getter HTMLAreaElement::download(string);\n
+setter HTMLAreaElement::download(string);\n
+getter HTMLAreaElement::hash(user);\n
+setter HTMLAreaElement::hash(user);\n
+getter HTMLAreaElement::hostname(user);\n
+setter HTMLAreaElement::hostname(user);\n
+getter HTMLAreaElement::host(user);\n
+setter HTMLAreaElement::host(user);\n
+getter HTMLAreaElement::hreflang(string);\n
+setter HTMLAreaElement::hreflang(string);\n
+getter HTMLAreaElement::href(user);\n
+setter HTMLAreaElement::href(user);\n
+getter HTMLAreaElement::origin(user);\n
+getter HTMLAreaElement::password(user);\n
+setter HTMLAreaElement::password(user);\n
+getter HTMLAreaElement::pathname(user);\n
+setter HTMLAreaElement::pathname(user);\n
+getter HTMLAreaElement::ping(user);\n
+getter HTMLAreaElement::port(user);\n
+setter HTMLAreaElement::port(user);\n
+getter HTMLAreaElement::protocol(user);\n
+setter HTMLAreaElement::protocol(user);\n
+getter HTMLAreaElement::relList(user);\n
+getter HTMLAreaElement::rel(string);\n
+setter HTMLAreaElement::rel(string);\n
+getter HTMLAreaElement::search(user);\n
+setter HTMLAreaElement::search(user);\n
+getter HTMLAreaElement::type(string);\n
+setter HTMLAreaElement::type(string);\n
+getter HTMLAreaElement::username(user);\n
+setter HTMLAreaElement::username(user);\n
+getter HTMLBodyElement::onafterprint(user);\n
+setter HTMLBodyElement::onafterprint(user);\n
+getter HTMLBodyElement::onbeforeprint(user);\n
+setter HTMLBodyElement::onbeforeprint(user);\n
+getter HTMLBodyElement::onbeforeunload(user);\n
+setter HTMLBodyElement::onbeforeunload(user);\n
+getter HTMLBodyElement::onhashchange(user);\n
+setter HTMLBodyElement::onhashchange(user);\n
+getter HTMLBodyElement::onlanguagechange(user);\n
+setter HTMLBodyElement::onlanguagechange(user);\n
+getter HTMLBodyElement::onmessage(user);\n
+setter HTMLBodyElement::onmessage(user);\n
+getter HTMLBodyElement::onoffline(user);\n
+setter HTMLBodyElement::onoffline(user);\n
+getter HTMLBodyElement::ononline(user);\n
+setter HTMLBodyElement::ononline(user);\n
+getter HTMLBodyElement::onpagehide(user);\n
+setter HTMLBodyElement::onpagehide(user);\n
+getter HTMLBodyElement::onpageshow(user);\n
+setter HTMLBodyElement::onpageshow(user);\n
+getter HTMLBodyElement::onpopstate(user);\n
+setter HTMLBodyElement::onpopstate(user);\n
+getter HTMLBodyElement::onstorage(user);\n
+setter HTMLBodyElement::onstorage(user);\n
+getter HTMLBodyElement::onunload(user);\n
+setter HTMLBodyElement::onunload(user);\n
+getter HTMLButtonElement::autofocus(boolean);\n
+setter HTMLButtonElement::autofocus(boolean);\n
+method HTMLButtonElement::checkValidity();\n
+getter HTMLButtonElement::formAction(string);\n
+setter HTMLButtonElement::formAction(string);\n
+getter HTMLButtonElement::formEnctype(string);\n
+setter HTMLButtonElement::formEnctype(string);\n
+getter HTMLButtonElement::formMethod(string);\n
+setter HTMLButtonElement::formMethod(string);\n
+getter HTMLButtonElement::formNoValidate(boolean);\n
+setter HTMLButtonElement::formNoValidate(boolean);\n
+getter HTMLButtonElement::formTarget(string);\n
+setter HTMLButtonElement::formTarget(string);\n
+getter HTMLButtonElement::form(user);\n
+getter HTMLButtonElement::labels(user);\n
+getter HTMLButtonElement::menu(user);\n
+setter HTMLButtonElement::menu(user);\n
+method HTMLButtonElement::reportValidity();\n
+method HTMLButtonElement::setCustomValidity();\n
+getter HTMLButtonElement::type(string);\n
+setter HTMLButtonElement::type(string);\n
+getter HTMLButtonElement::validationMessage(string);\n
+getter HTMLButtonElement::validity(user);\n
+getter HTMLButtonElement::willValidate(boolean);\n
+method HTMLCanvasElement::getContext();\n
+getter HTMLCanvasElement::height(unsigned long);\n
+setter HTMLCanvasElement::height(unsigned long);\n
+method HTMLCanvasElement::probablySupportsContext();\n
+method HTMLCanvasElement::setContext();\n
+method HTMLCanvasElement::toBlob();\n
+method HTMLCanvasElement::toDataURL();\n
+method HTMLCanvasElement::transferControlToProxy();\n
+getter HTMLCanvasElement::width(unsigned long);\n
+setter HTMLCanvasElement::width(unsigned long);\n
+method HTMLCollection::item();\n
+getter HTMLCollection::length(unsigned long);\n
+method HTMLCollection::namedItem();\n
+getter HTMLDataElement::value(string);\n
+setter HTMLDataElement::value(string);\n
+getter HTMLDataListElement::options(user);\n
+getter HTMLDetailsElement::open(boolean);\n
+setter HTMLDetailsElement::open(boolean);\n
+method HTMLDialogElement::close();\n
+getter HTMLDialogElement::open(boolean);\n
+setter HTMLDialogElement::open(boolean);\n
+getter HTMLDialogElement::returnValue(string);\n
+setter HTMLDialogElement::returnValue(string);\n
+method HTMLDialogElement::show();\n
+method HTMLDialogElement::showModal();\n
+getter HTMLDirectoryElement::compact(boolean);\n
+setter HTMLDirectoryElement::compact(boolean);\n
+getter HTMLDListElement::compact(boolean);\n
+setter HTMLDListElement::compact(boolean);\n
+getter HTMLElement::accessKeyLabel(string);\n
+getter HTMLElement::accessKey(string);\n
+setter HTMLElement::accessKey(string);\n
+method HTMLElement::blur();\n
+method HTMLElement::click();\n
+getter HTMLElement::commandChecked(boolean);\n
+getter HTMLElement::commandDisabled(boolean);\n
+getter HTMLElement::commandHidden(boolean);\n
+getter HTMLElement::commandIcon(string);\n
+getter HTMLElement::commandLabel(string);\n
+getter HTMLElement::commandType(string);\n
+getter HTMLElement::contentEditable(string);\n
+setter HTMLElement::contentEditable(string);\n
+getter HTMLElement::contextMenu(user);\n
+setter HTMLElement::contextMenu(user);\n
+getter HTMLElement::dataset(user);\n
+getter HTMLElement::draggable(boolean);\n
+setter HTMLElement::draggable(boolean);\n
+getter HTMLElement::dropzone(user);\n
+method HTMLElement::focus();\n
+method HTMLElement::forceSpellCheck();\n
+getter HTMLElement::hidden(boolean);\n
+setter HTMLElement::hidden(boolean);\n
+getter HTMLElement::isContentEditable(boolean);\n
+getter HTMLElement::onerror(user);\n
+setter HTMLElement::onerror(user);\n
+getter HTMLElement::spellcheck(boolean);\n
+setter HTMLElement::spellcheck(boolean);\n
+getter HTMLElement::style(user);\n
+getter HTMLElement::tabIndex(long);\n
+setter HTMLElement::tabIndex(long);\n
+getter HTMLElement::translate(boolean);\n
+setter HTMLElement::translate(boolean);\n
+getter HTMLEmbedElement::align(string);\n
+setter HTMLEmbedElement::align(string);\n
+method HTMLEmbedElement::getSVGDocument();\n
+getter HTMLEmbedElement::height(string);\n
+setter HTMLEmbedElement::height(string);\n
+getter HTMLEmbedElement::name(string);\n
+setter HTMLEmbedElement::name(string);\n
+getter HTMLEmbedElement::src(string);\n
+setter HTMLEmbedElement::src(string);\n
+getter HTMLEmbedElement::type(string);\n
+setter HTMLEmbedElement::type(string);\n
+getter HTMLEmbedElement::width(string);\n
+setter HTMLEmbedElement::width(string);\n
+method HTMLFieldSetElement::checkValidity();\n
+getter HTMLFieldSetElement::disabled(boolean);\n
+setter HTMLFieldSetElement::disabled(boolean);\n
+getter HTMLFieldSetElement::elements(user);\n
+getter HTMLFieldSetElement::form(user);\n
+getter HTMLFieldSetElement::name(string);\n
+setter HTMLFieldSetElement::name(string);\n
+method HTMLFieldSetElement::reportValidity();\n
+method HTMLFieldSetElement::setCustomValidity();\n
+getter HTMLFieldSetElement::type(string);\n
+getter HTMLFieldSetElement::validationMessage(string);\n
+getter HTMLFieldSetElement::validity(user);\n
+getter HTMLFieldSetElement::willValidate(boolean);\n
+method HTMLFormControlsCollection::namedItem();\n
+getter HTMLFormElement::autocomplete(string);\n
+setter HTMLFormElement::autocomplete(string);\n
+method HTMLFormElement::checkValidity();\n
+getter HTMLFormElement::elements(user);\n
+getter HTMLFormElement::encoding(string);\n
+setter HTMLFormElement::encoding(string);\n
+getter HTMLFormElement::length(long);\n
+getter HTMLFormElement::name(string);\n
+setter HTMLFormElement::name(string);\n
+getter HTMLFormElement::noValidate(boolean);\n
+setter HTMLFormElement::noValidate(boolean);\n
+method HTMLFormElement::reportValidity();\n
+method HTMLFormElement::requestAutocomplete();\n
+method HTMLFormElement::reset();\n
+method HTMLFormElement::submit();\n
+getter HTMLFrameElement::contentDocument(user);\n
+getter HTMLFrameElement::contentWindow(user);\n
+getter HTMLFrameSetElement::onafterprint(user);\n
+setter HTMLFrameSetElement::onafterprint(user);\n
+getter HTMLFrameSetElement::onbeforeprint(user);\n
+setter HTMLFrameSetElement::onbeforeprint(user);\n
+getter HTMLFrameSetElement::onbeforeunload(user);\n
+setter HTMLFrameSetElement::onbeforeunload(user);\n
+getter HTMLFrameSetElement::onhashchange(user);\n
+setter HTMLFrameSetElement::onhashchange(user);\n
+getter HTMLFrameSetElement::onlanguagechange(user);\n
+setter HTMLFrameSetElement::onlanguagechange(user);\n
+getter HTMLFrameSetElement::onmessage(user);\n
+setter HTMLFrameSetElement::onmessage(user);\n
+getter HTMLFrameSetElement::onoffline(user);\n
+setter HTMLFrameSetElement::onoffline(user);\n
+getter HTMLFrameSetElement::ononline(user);\n
+setter HTMLFrameSetElement::ononline(user);\n
+getter HTMLFrameSetElement::onpagehide(user);\n
+setter HTMLFrameSetElement::onpagehide(user);\n
+getter HTMLFrameSetElement::onpageshow(user);\n
+setter HTMLFrameSetElement::onpageshow(user);\n
+getter HTMLFrameSetElement::onpopstate(user);\n
+setter HTMLFrameSetElement::onpopstate(user);\n
+getter HTMLFrameSetElement::onstorage(user);\n
+setter HTMLFrameSetElement::onstorage(user);\n
+getter HTMLFrameSetElement::onunload(user);\n
+setter HTMLFrameSetElement::onunload(user);\n
+getter HTMLHRElement::color(string);\n
+setter HTMLHRElement::color(string);\n
+getter HTMLIFrameElement::allowFullscreen(boolean);\n
+setter HTMLIFrameElement::allowFullscreen(boolean);\n
+getter HTMLIFrameElement::contentDocument(user);\n
+getter HTMLIFrameElement::contentWindow(user);\n
+method HTMLIFrameElement::getSVGDocument();\n
+getter HTMLIFrameElement::sandbox(user);\n
+getter HTMLIFrameElement::seamless(boolean);\n
+setter HTMLIFrameElement::seamless(boolean);\n
+getter HTMLIFrameElement::srcdoc(string);\n
+setter HTMLIFrameElement::srcdoc(string);\n
+getter HTMLImageElement::complete(boolean);\n
+getter HTMLImageElement::crossOrigin(string);\n
+setter HTMLImageElement::crossOrigin(string);\n
+getter HTMLImageElement::currentSrc(string);\n
+getter HTMLImageElement::lowsrc(string);\n
+setter HTMLImageElement::lowsrc(string);\n
+getter HTMLImageElement::naturalHeight(unsigned long);\n
+getter HTMLImageElement::naturalWidth(unsigned long);\n
+getter HTMLImageElement::sizes(string);\n
+setter HTMLImageElement::sizes(string);\n
+getter HTMLImageElement::srcset(string);\n
+setter HTMLImageElement::srcset(string);\n
+getter HTMLInputElement::autocomplete(string);\n
+setter HTMLInputElement::autocomplete(string);\n
+getter HTMLInputElement::autofocus(boolean);\n
+setter HTMLInputElement::autofocus(boolean);\n
+method HTMLInputElement::checkValidity();\n
+getter HTMLInputElement::dirName(string);\n
+setter HTMLInputElement::dirName(string);\n
+getter HTMLInputElement::files(user);\n
+getter HTMLInputElement::formAction(string);\n
+setter HTMLInputElement::formAction(string);\n
+getter HTMLInputElement::formEnctype(string);\n
+setter HTMLInputElement::formEnctype(string);\n
+getter HTMLInputElement::formMethod(string);\n
+setter HTMLInputElement::formMethod(string);\n
+getter HTMLInputElement::formNoValidate(boolean);\n
+setter HTMLInputElement::formNoValidate(boolean);\n
+getter HTMLInputElement::formTarget(string);\n
+setter HTMLInputElement::formTarget(string);\n
+getter HTMLInputElement::form(user);\n
+getter HTMLInputElement::height(unsigned long);\n
+setter HTMLInputElement::height(unsigned long);\n
+getter HTMLInputElement::indeterminate(boolean);\n
+setter HTMLInputElement::indeterminate(boolean);\n
+getter HTMLInputElement::inputMode(string);\n
+setter HTMLInputElement::inputMode(string);\n
+getter HTMLInputElement::labels(user);\n
+getter HTMLInputElement::list(user);\n
+getter HTMLInputElement::max(string);\n
+setter HTMLInputElement::max(string);\n
+getter HTMLInputElement::minLength(long);\n
+setter HTMLInputElement::minLength(long);\n
+getter HTMLInputElement::min(string);\n
+setter HTMLInputElement::min(string);\n
+getter HTMLInputElement::multiple(boolean);\n
+setter HTMLInputElement::multiple(boolean);\n
+getter HTMLInputElement::pattern(string);\n
+setter HTMLInputElement::pattern(string);\n
+getter HTMLInputElement::placeholder(string);\n
+setter HTMLInputElement::placeholder(string);\n
+method HTMLInputElement::reportValidity();\n
+getter HTMLInputElement::required(boolean);\n
+setter HTMLInputElement::required(boolean);\n
+method HTMLInputElement::select();\n
+getter HTMLInputElement::selectionDirection(string);\n
+setter HTMLInputElement::selectionDirection(string);\n
+getter HTMLInputElement::selectionEnd(unsigned long);\n
+setter HTMLInputElement::selectionEnd(unsigned long);\n
+getter HTMLInputElement::selectionStart(unsigned long);\n
+setter HTMLInputElement::selectionStart(unsigned long);\n
+method HTMLInputElement::setCustomValidity();\n
+method HTMLInputElement::setRangeText();\n
+method HTMLInputElement::setSelectionRange();\n
+method HTMLInputElement::stepDown();\n
+getter HTMLInputElement::step(string);\n
+setter HTMLInputElement::step(string);\n
+method HTMLInputElement::stepUp();\n
+setter HTMLInputElement::type(string);\n
+getter HTMLInputElement::validationMessage(string);\n
+getter HTMLInputElement::validity(user);\n
+getter HTMLInputElement::valueAsDate(date);\n
+setter HTMLInputElement::valueAsDate(date);\n
+getter HTMLInputElement::valueAsNumber(double);\n
+setter HTMLInputElement::valueAsNumber(double);\n
+getter HTMLInputElement::valueHigh(double);\n
+setter HTMLInputElement::valueHigh(double);\n
+getter HTMLInputElement::valueLow(double);\n
+setter HTMLInputElement::valueLow(double);\n
+getter HTMLInputElement::width(unsigned long);\n
+setter HTMLInputElement::width(unsigned long);\n
+getter HTMLInputElement::willValidate(boolean);\n
+getter HTMLKeygenElement::autofocus(boolean);\n
+setter HTMLKeygenElement::autofocus(boolean);\n
+getter HTMLKeygenElement::challenge(string);\n
+setter HTMLKeygenElement::challenge(string);\n
+method HTMLKeygenElement::checkValidity();\n
+getter HTMLKeygenElement::disabled(boolean);\n
+setter HTMLKeygenElement::disabled(boolean);\n
+getter HTMLKeygenElement::form(user);\n
+getter HTMLKeygenElement::keytype(string);\n
+setter HTMLKeygenElement::keytype(string);\n
+getter HTMLKeygenElement::labels(user);\n
+getter HTMLKeygenElement::name(string);\n
+setter HTMLKeygenElement::name(string);\n
+method HTMLKeygenElement::reportValidity();\n
+method HTMLKeygenElement::setCustomValidity();\n
+getter HTMLKeygenElement::type(string);\n
+getter HTMLKeygenElement::validationMessage(string);\n
+getter HTMLKeygenElement::validity(user);\n
+getter HTMLKeygenElement::willValidate(boolean);\n
+getter HTMLLabelElement::control(user);\n
+getter HTMLLabelElement::form(user);\n
+getter HTMLLegendElement::form(user);\n
+getter HTMLLinkElement::crossOrigin(string);\n
+setter HTMLLinkElement::crossOrigin(string);\n
+getter HTMLLinkElement::relList(user);\n
+getter HTMLLinkElement::sheet(user);\n
+getter HTMLLinkElement::sizes(user);\n
+getter HTMLMapElement::areas(user);\n
+getter HTMLMarqueeElement::behavior(string);\n
+setter HTMLMarqueeElement::behavior(string);\n
+getter HTMLMarqueeElement::bgColor(string);\n
+setter HTMLMarqueeElement::bgColor(string);\n
+getter HTMLMarqueeElement::direction(string);\n
+setter HTMLMarqueeElement::direction(string);\n
+getter HTMLMarqueeElement::height(string);\n
+setter HTMLMarqueeElement::height(string);\n
+getter HTMLMarqueeElement::hspace(unsigned long);\n
+setter HTMLMarqueeElement::hspace(unsigned long);\n
+getter HTMLMarqueeElement::loop(long);\n
+setter HTMLMarqueeElement::loop(long);\n
+getter HTMLMarqueeElement::onbounce(user);\n
+setter HTMLMarqueeElement::onbounce(user);\n
+getter HTMLMarqueeElement::onfinish(user);\n
+setter HTMLMarqueeElement::onfinish(user);\n
+getter HTMLMarqueeElement::onstart(user);\n
+setter HTMLMarqueeElement::onstart(user);\n
+getter HTMLMarqueeElement::scrollAmount(unsigned long);\n
+setter HTMLMarqueeElement::scrollAmount(unsigned long);\n
+getter HTMLMarqueeElement::scrollDelay(unsigned long);\n
+setter HTMLMarqueeElement::scrollDelay(unsigned long);\n
+method HTMLMarqueeElement::start();\n
+method HTMLMarqueeElement::stop();\n
+getter HTMLMarqueeElement::trueSpeed(boolean);\n
+setter HTMLMarqueeElement::trueSpeed(boolean);\n
+getter HTMLMarqueeElement::vspace(unsigned long);\n
+setter HTMLMarqueeElement::vspace(unsigned long);\n
+getter HTMLMarqueeElement::width(string);\n
+setter HTMLMarqueeElement::width(string);\n
+method HTMLMediaElement::addTextTrack();\n
+getter HTMLMediaElement::audioTracks(user);\n
+getter HTMLMediaElement::autoplay(boolean);\n
+setter HTMLMediaElement::autoplay(boolean);\n
+getter HTMLMediaElement::buffered(user);\n
+method HTMLMediaElement::canPlayType();\n
+getter HTMLMediaElement::controller(user);\n
+setter HTMLMediaElement::controller(user);\n
+getter HTMLMediaElement::controls(boolean);\n
+setter HTMLMediaElement::controls(boolean);\n
+getter HTMLMediaElement::crossOrigin(string);\n
+setter HTMLMediaElement::crossOrigin(string);\n
+getter HTMLMediaElement::currentSrc(string);\n
+getter HTMLMediaElement::currentTime(double);\n
+setter HTMLMediaElement::currentTime(double);\n
+getter HTMLMediaElement::defaultMuted(boolean);\n
+setter HTMLMediaElement::defaultMuted(boolean);\n
+getter HTMLMediaElement::defaultPlaybackRate(double);\n
+setter HTMLMediaElement::defaultPlaybackRate(double);\n
+getter HTMLMediaElement::duration(double);\n
+getter HTMLMediaElement::ended(boolean);\n
+getter HTMLMediaElement::error(user);\n
+method HTMLMediaElement::fastSeek();\n
+method HTMLMediaElement::getStartDate();\n
+method HTMLMediaElement::load();\n
+getter HTMLMediaElement::loop(boolean);\n
+setter HTMLMediaElement::loop(boolean);\n
+getter HTMLMediaElement::mediaGroup(string);\n
+setter HTMLMediaElement::mediaGroup(string);\n
+getter HTMLMediaElement::muted(boolean);\n
+setter HTMLMediaElement::muted(boolean);\n
+getter HTMLMediaElement::networkState(unsigned short);\n
+method HTMLMediaElement::pause();\n
+getter HTMLMediaElement::paused(boolean);\n
+method HTMLMediaElement::play();\n
+getter HTMLMediaElement::playbackRate(double);\n
+setter HTMLMediaElement::playbackRate(double);\n
+getter HTMLMediaElement::played(user);\n
+getter HTMLMediaElement::preload(string);\n
+setter HTMLMediaElement::preload(string);\n
+getter HTMLMediaElement::readyState(unsigned short);\n
+getter HTMLMediaElement::seekable(user);\n
+getter HTMLMediaElement::seeking(boolean);\n
+getter HTMLMediaElement::srcObject(user);\n
+setter HTMLMediaElement::srcObject(user);\n
+getter HTMLMediaElement::src(string);\n
+setter HTMLMediaElement::src(string);\n
+getter HTMLMediaElement::textTracks(user);\n
+getter HTMLMediaElement::videoTracks(user);\n
+getter HTMLMediaElement::volume(double);\n
+setter HTMLMediaElement::volume(double);\n
+getter HTMLMenuElement::label(string);\n
+setter HTMLMenuElement::label(string);\n
+getter HTMLMenuElement::type(string);\n
+setter HTMLMenuElement::type(string);\n
+getter HTMLMenuItemElement::checked(boolean);\n
+setter HTMLMenuItemElement::checked(boolean);\n
+getter HTMLMenuItemElement::command(user);\n
+getter HTMLMenuItemElement::default(boolean);\n
+setter HTMLMenuItemElement::default(boolean);\n
+getter HTMLMenuItemElement::disabled(boolean);\n
+setter HTMLMenuItemElement::disabled(boolean);\n
+getter HTMLMenuItemElement::icon(string);\n
+setter HTMLMenuItemElement::icon(string);\n
+getter HTMLMenuItemElement::label(string);\n
+setter HTMLMenuItemElement::label(string);\n
+getter HTMLMenuItemElement::radiogroup(string);\n
+setter HTMLMenuItemElement::radiogroup(string);\n
+getter HTMLMenuItemElement::type(string);\n
+setter HTMLMenuItemElement::type(string);\n
+getter HTMLMeterElement::high(double);\n
+setter HTMLMeterElement::high(double);\n
+getter HTMLMeterElement::labels(user);\n
+getter HTMLMeterElement::low(double);\n
+setter HTMLMeterElement::low(double);\n
+getter HTMLMeterElement::max(double);\n
+setter HTMLMeterElement::max(double);\n
+getter HTMLMeterElement::min(double);\n
+setter HTMLMeterElement::min(double);\n
+getter HTMLMeterElement::optimum(double);\n
+setter HTMLMeterElement::optimum(double);\n
+getter HTMLMeterElement::value(double);\n
+setter HTMLMeterElement::value(double);\n
+getter HTMLModElement::cite(string);\n
+setter HTMLModElement::cite(string);\n
+getter HTMLModElement::dateTime(string);\n
+setter HTMLModElement::dateTime(string);\n
+method HTMLObjectElement::checkValidity();\n
+getter HTMLObjectElement::contentDocument(user);\n
+getter HTMLObjectElement::contentWindow(user);\n
+getter HTMLObjectElement::form(user);\n
+method HTMLObjectElement::getSVGDocument();\n
+getter HTMLObjectElement::hspace(unsigned long);\n
+setter HTMLObjectElement::hspace(unsigned long);\n
+method HTMLObjectElement::reportValidity();\n
+method HTMLObjectElement::setCustomValidity();\n
+getter HTMLObjectElement::typeMustMatch(boolean);\n
+setter HTMLObjectElement::typeMustMatch(boolean);\n
+getter HTMLObjectElement::validationMessage(string);\n
+getter HTMLObjectElement::validity(user);\n
+getter HTMLObjectElement::vspace(unsigned long);\n
+setter HTMLObjectElement::vspace(unsigned long);\n
+getter HTMLObjectElement::willValidate(boolean);\n
+getter HTMLOListElement::reversed(boolean);\n
+setter HTMLOListElement::reversed(boolean);\n
+getter HTMLOptGroupElement::disabled(boolean);\n
+setter HTMLOptGroupElement::disabled(boolean);\n
+getter HTMLOptGroupElement::label(string);\n
+setter HTMLOptGroupElement::label(string);\n
+getter HTMLOptionElement::form(user);\n
+getter HTMLOptionElement::index(long);\n
+setter HTMLOptionElement::text(string);\n
+method HTMLOptionsCollection::add();\n
+getter HTMLOptionsCollection::length(unsigned long);\n
+setter HTMLOptionsCollection::length(unsigned long);\n
+method HTMLOptionsCollection::remove();\n
+getter HTMLOptionsCollection::selectedIndex(long);\n
+setter HTMLOptionsCollection::selectedIndex(long);\n
+method HTMLOutputElement::checkValidity();\n
+getter HTMLOutputElement::defaultValue(string);\n
+setter HTMLOutputElement::defaultValue(string);\n
+getter HTMLOutputElement::form(user);\n
+getter HTMLOutputElement::htmlFor(user);\n
+getter HTMLOutputElement::labels(user);\n
+getter HTMLOutputElement::name(string);\n
+setter HTMLOutputElement::name(string);\n
+method HTMLOutputElement::reportValidity();\n
+method HTMLOutputElement::setCustomValidity();\n
+getter HTMLOutputElement::type(string);\n
+getter HTMLOutputElement::validationMessage(string);\n
+getter HTMLOutputElement::validity(user);\n
+getter HTMLOutputElement::value(string);\n
+setter HTMLOutputElement::value(string);\n
+getter HTMLOutputElement::willValidate(boolean);\n
+getter HTMLProgressElement::labels(user);\n
+getter HTMLProgressElement::max(double);\n
+setter HTMLProgressElement::max(double);\n
+getter HTMLProgressElement::position(double);\n
+getter HTMLProgressElement::value(double);\n
+setter HTMLProgressElement::value(double);\n
+getter HTMLScriptElement::async(boolean);\n
+setter HTMLScriptElement::async(boolean);\n
+getter HTMLScriptElement::crossOrigin(string);\n
+setter HTMLScriptElement::crossOrigin(string);\n
+getter HTMLScriptElement::nonce(string);\n
+setter HTMLScriptElement::nonce(string);\n
+method HTMLSelectElement::add();\n
+getter HTMLSelectElement::autocomplete(string);\n
+setter HTMLSelectElement::autocomplete(string);\n
+getter HTMLSelectElement::autofocus(boolean);\n
+setter HTMLSelectElement::autofocus(boolean);\n
+method HTMLSelectElement::checkValidity();\n
+getter HTMLSelectElement::form(user);\n
+method HTMLSelectElement::item();\n
+getter HTMLSelectElement::labels(user);\n
+getter HTMLSelectElement::length(unsigned long);\n
+setter HTMLSelectElement::length(unsigned long);\n
+method HTMLSelectElement::namedItem();\n
+getter HTMLSelectElement::options(user);\n
+method HTMLSelectElement::remove();\n
+method HTMLSelectElement::reportValidity();\n
+getter HTMLSelectElement::required(boolean);\n
+setter HTMLSelectElement::required(boolean);\n
+getter HTMLSelectElement::selectedIndex(long);\n
+setter HTMLSelectElement::selectedIndex(long);\n
+getter HTMLSelectElement::selectedOptions(user);\n
+method HTMLSelectElement::setCustomValidity();\n
+getter HTMLSelectElement::size(unsigned long);\n
+setter HTMLSelectElement::size(unsigned long);\n
+getter HTMLSelectElement::validationMessage(string);\n
+getter HTMLSelectElement::validity(user);\n
+getter HTMLSelectElement::willValidate(boolean);\n
+getter HTMLSourceElement::media(string);\n
+setter HTMLSourceElement::media(string);\n
+getter HTMLSourceElement::sizes(string);\n
+setter HTMLSourceElement::sizes(string);\n
+getter HTMLSourceElement::srcset(string);\n
+setter HTMLSourceElement::srcset(string);\n
+getter HTMLSourceElement::src(string);\n
+setter HTMLSourceElement::src(string);\n
+getter HTMLSourceElement::type(string);\n
+setter HTMLSourceElement::type(string);\n
+getter HTMLStyleElement::nonce(string);\n
+setter HTMLStyleElement::nonce(string);\n
+getter HTMLStyleElement::scoped(boolean);\n
+setter HTMLStyleElement::scoped(boolean);\n
+getter HTMLStyleElement::sheet(user);\n
+getter HTMLTableCellElement::headers(user);\n
+getter HTMLTableColElement::span(unsigned long);\n
+setter HTMLTableColElement::span(unsigned long);\n
+getter HTMLTableDataCellElement::abbr(string);\n
+setter HTMLTableDataCellElement::abbr(string);\n
+getter HTMLTableElement::caption(user);\n
+setter HTMLTableElement::caption(user);\n
+method HTMLTableElement::createCaption();\n
+method HTMLTableElement::createTBody();\n
+method HTMLTableElement::createTFoot();\n
+method HTMLTableElement::createTHead();\n
+method HTMLTableElement::deleteCaption();\n
+method HTMLTableElement::deleteRow();\n
+method HTMLTableElement::deleteTFoot();\n
+method HTMLTableElement::deleteTHead();\n
+method HTMLTableElement::insertRow();\n
+getter HTMLTableElement::rows(user);\n
+getter HTMLTableElement::sortable(boolean);\n
+setter HTMLTableElement::sortable(boolean);\n
+method HTMLTableElement::stopSorting();\n
+getter HTMLTableElement::tBodies(user);\n
+getter HTMLTableElement::tFoot(user);\n
+setter HTMLTableElement::tFoot(user);\n
+getter HTMLTableElement::tHead(user);\n
+setter HTMLTableElement::tHead(user);\n
+getter HTMLTableHeaderCellElement::abbr(string);\n
+setter HTMLTableHeaderCellElement::abbr(string);\n
+getter HTMLTableHeaderCellElement::scope(string);\n
+setter HTMLTableHeaderCellElement::scope(string);\n
+method HTMLTableHeaderCellElement::sort();\n
+getter HTMLTableHeaderCellElement::sorted(string);\n
+setter HTMLTableHeaderCellElement::sorted(string);\n
+getter HTMLTableRowElement::cells(user);\n
+method HTMLTableRowElement::deleteCell();\n
+method HTMLTableRowElement::insertCell();\n
+method HTMLTableSectionElement::deleteRow();\n
+method HTMLTableSectionElement::insertRow();\n
+getter HTMLTableSectionElement::rows(user);\n
+getter HTMLTemplateElement::content(user);\n
+getter HTMLTextAreaElement::autocomplete(string);\n
+setter HTMLTextAreaElement::autocomplete(string);\n
+getter HTMLTextAreaElement::autofocus(boolean);\n
+setter HTMLTextAreaElement::autofocus(boolean);\n
+method HTMLTextAreaElement::checkValidity();\n
+getter HTMLTextAreaElement::cols(unsigned long);\n
+setter HTMLTextAreaElement::cols(unsigned long);\n
+getter HTMLTextAreaElement::dirName(string);\n
+setter HTMLTextAreaElement::dirName(string);\n
+getter HTMLTextAreaElement::form(user);\n
+getter HTMLTextAreaElement::inputMode(string);\n
+setter HTMLTextAreaElement::inputMode(string);\n
+getter HTMLTextAreaElement::labels(user);\n
+getter HTMLTextAreaElement::maxLength(long);\n
+setter HTMLTextAreaElement::maxLength(long);\n
+getter HTMLTextAreaElement::minLength(long);\n
+setter HTMLTextAreaElement::minLength(long);\n
+getter HTMLTextAreaElement::placeholder(string);\n
+setter HTMLTextAreaElement::placeholder(string);\n
+method HTMLTextAreaElement::reportValidity();\n
+getter HTMLTextAreaElement::required(boolean);\n
+setter HTMLTextAreaElement::required(boolean);\n
+getter HTMLTextAreaElement::rows(unsigned long);\n
+setter HTMLTextAreaElement::rows(unsigned long);\n
+method HTMLTextAreaElement::select();\n
+getter HTMLTextAreaElement::selectionDirection(string);\n
+setter HTMLTextAreaElement::selectionDirection(string);\n
+getter HTMLTextAreaElement::selectionEnd(unsigned long);\n
+setter HTMLTextAreaElement::selectionEnd(unsigned long);\n
+getter HTMLTextAreaElement::selectionStart(unsigned long);\n
+setter HTMLTextAreaElement::selectionStart(unsigned long);\n
+method HTMLTextAreaElement::setCustomValidity();\n
+method HTMLTextAreaElement::setRangeText();\n
+method HTMLTextAreaElement::setSelectionRange();\n
+getter HTMLTextAreaElement::textLength(unsigned long);\n
+getter HTMLTextAreaElement::validationMessage(string);\n
+getter HTMLTextAreaElement::validity(user);\n
+getter HTMLTextAreaElement::willValidate(boolean);\n
+getter HTMLTextAreaElement::wrap(string);\n
+setter HTMLTextAreaElement::wrap(string);\n
+getter HTMLTimeElement::dateTime(string);\n
+setter HTMLTimeElement::dateTime(string);\n
+getter HTMLTrackElement::default(boolean);\n
+setter HTMLTrackElement::default(boolean);\n
+getter HTMLTrackElement::kind(string);\n
+setter HTMLTrackElement::kind(string);\n
+getter HTMLTrackElement::label(string);\n
+setter HTMLTrackElement::label(string);\n
+getter HTMLTrackElement::readyState(unsigned short);\n
+getter HTMLTrackElement::srclang(string);\n
+setter HTMLTrackElement::srclang(string);\n
+getter HTMLTrackElement::src(string);\n
+setter HTMLTrackElement::src(string);\n
+getter HTMLTrackElement::track(user);\n
+getter HTMLUListElement::compact(boolean);\n
+setter HTMLUListElement::compact(boolean);\n
+getter HTMLUListElement::type(string);\n
+setter HTMLUListElement::type(string);\n
+getter HTMLVideoElement::height(unsigned long);\n
+setter HTMLVideoElement::height(unsigned long);\n
+getter HTMLVideoElement::poster(string);\n
+setter HTMLVideoElement::poster(string);\n
+getter HTMLVideoElement::videoHeight(unsigned long);\n
+getter HTMLVideoElement::videoWidth(unsigned long);\n
+getter HTMLVideoElement::width(unsigned long);\n
+setter HTMLVideoElement::width(unsigned long);\n
+getter ImageBitmap::height(unsigned long);\n
+getter ImageBitmap::width(unsigned long);\n
+getter ImageData::data(user);\n
+getter ImageData::height(unsigned long);\n
+getter ImageData::width(unsigned long);\n
+getter KeyboardEvent::altKey(boolean);\n
+getter KeyboardEvent::charCode(unsigned long);\n
+getter KeyboardEvent::code(string);\n
+getter KeyboardEvent::ctrlKey(boolean);\n
+method KeyboardEvent::getModifierState();\n
+method KeyboardEvent::initKeyboardEvent();\n
+getter KeyboardEvent::isComposing(boolean);\n
+getter KeyboardEvent::keyCode(unsigned long);\n
+getter KeyboardEvent::key(string);\n
+getter KeyboardEvent::location(unsigned long);\n
+getter KeyboardEvent::metaKey(boolean);\n
+getter KeyboardEvent::repeat(boolean);\n
+getter KeyboardEvent::shiftKey(boolean);\n
+getter KeyboardEvent::which(unsigned long);\n
+getter Location::ancestorOrigins(string);\n
+setter Location::hash(user);\n
+setter Location::hostname(user);\n
+setter Location::host(user);\n
+setter Location::password(user);\n
+setter Location::pathname(user);\n
+setter Location::port(user);\n
+setter Location::protocol(user);\n
+setter Location::search(user);\n
+setter Location::username(user);\n
+getter MediaController::buffered(user);\n
+getter MediaController::currentTime(double);\n
+setter MediaController::currentTime(double);\n
+getter MediaController::defaultPlaybackRate(double);\n
+setter MediaController::defaultPlaybackRate(double);\n
+getter MediaController::duration(double);\n
+getter MediaController::muted(boolean);\n
+setter MediaController::muted(boolean);\n
+getter MediaController::oncanplaythrough(user);\n
+setter MediaController::oncanplaythrough(user);\n
+getter MediaController::oncanplay(user);\n
+setter MediaController::oncanplay(user);\n
+getter MediaController::ondurationchange(user);\n
+setter MediaController::ondurationchange(user);\n
+getter MediaController::onemptied(user);\n
+setter MediaController::onemptied(user);\n
+getter MediaController::onended(user);\n
+setter MediaController::onended(user);\n
+getter MediaController::onloadeddata(user);\n
+setter MediaController::onloadeddata(user);\n
+getter MediaController::onloadedmetadata(user);\n
+setter MediaController::onloadedmetadata(user);\n
+getter MediaController::onpause(user);\n
+setter MediaController::onpause(user);\n
+getter MediaController::onplaying(user);\n
+setter MediaController::onplaying(user);\n
+getter MediaController::onplay(user);\n
+setter MediaController::onplay(user);\n
+getter MediaController::onratechange(user);\n
+setter MediaController::onratechange(user);\n
+getter MediaController::ontimeupdate(user);\n
+setter MediaController::ontimeupdate(user);\n
+getter MediaController::onvolumechange(user);\n
+setter MediaController::onvolumechange(user);\n
+getter MediaController::onwaiting(user);\n
+setter MediaController::onwaiting(user);\n
+method MediaController::pause();\n
+getter MediaController::paused(boolean);\n
+method MediaController::play();\n
+getter MediaController::playbackRate(double);\n
+setter MediaController::playbackRate(double);\n
+getter MediaController::playbackState(user);\n
+getter MediaController::played(user);\n
+getter MediaController::readyState(unsigned short);\n
+getter MediaController::seekable(user);\n
+method MediaController::unpause();\n
+getter MediaController::volume(double);\n
+setter MediaController::volume(double);\n
+getter MediaError::code(unsigned short);\n
+method MediaList::appendMedium();\n
+method MediaList::deleteMedium();\n
+method MediaList::item();\n
+getter MediaList::length(unsigned long);\n
+getter MediaList::mediaText(string);\n
+setter MediaList::mediaText(string);\n
+getter MessageChannel::port1(user);\n
+getter MessageChannel::port2(user);\n
+getter MessageEvent::data(any);\n
+method MessageEvent::initMessageEvent();\n
+getter MessageEvent::lastEventId(string);\n
+getter MessageEvent::origin(string);\n
+getter MessageEvent::ports(user);\n
+getter MessageEvent::source(multiple);\n
+method MessagePort::close();\n
+getter MessagePort::onmessage(user);\n
+setter MessagePort::onmessage(user);\n
+method MessagePort::postMessage();\n
+method MessagePort::start();\n
+method MimeTypeArray::item();\n
+getter MimeTypeArray::length(unsigned long);\n
+method MimeTypeArray::namedItem();\n
+getter MimeType::description(string);\n
+getter MimeType::enabledPlugin(user);\n
+getter MimeType::suffixes(string);\n
+getter MimeType::type(string);\n
+getter MouseEvent::altKey(boolean);\n
+getter MouseEvent::button(short);\n
+getter MouseEvent::buttons(unsigned short);\n
+getter MouseEvent::clientX(long);\n
+getter MouseEvent::clientY(long);\n
+getter MouseEvent::ctrlKey(boolean);\n
+method MouseEvent::getModifierState();\n
+method MouseEvent::initMouseEvent();\n
+getter MouseEvent::metaKey(boolean);\n
+getter MouseEvent::region(string);\n
+getter MouseEvent::relatedTarget(user);\n
+getter MouseEvent::screenX(long);\n
+getter MouseEvent::screenY(long);\n
+getter MouseEvent::shiftKey(boolean);\n
+getter MutationEvent::attrChange(unsigned short);\n
+getter MutationEvent::attrName(string);\n
+method MutationEvent::initMutationEvent();\n
+getter MutationEvent::newValue(string);\n
+getter MutationEvent::prevValue(string);\n
+getter MutationEvent::relatedNode(user);\n
+method MutationObserver::disconnect();\n
+method MutationObserver::observe();\n
+method MutationObserver::takeRecords();\n
+getter MutationRecord::addedNodes(user);\n
+getter MutationRecord::attributeNamespace(string);\n
+getter MutationRecord::attributeName(string);\n
+getter MutationRecord::nextSibling(user);\n
+getter MutationRecord::oldValue(string);\n
+getter MutationRecord::previousSibling(user);\n
+getter MutationRecord::removedNodes(user);\n
+getter MutationRecord::target(user);\n
+getter MutationRecord::type(string);\n
+method NamedNodeMap::getNamedItem();\n
+method NamedNodeMap::getNamedItemNS();\n
+method NamedNodeMap::item();\n
+getter NamedNodeMap::length(unsigned long);\n
+method NamedNodeMap::removeNamedItem();\n
+method NamedNodeMap::removeNamedItemNS();\n
+method NamedNodeMap::setNamedItem();\n
+method NamedNodeMap::setNamedItemNS();\n
+method Navigator::isContentHandlerRegistered();\n
+method Navigator::isProtocolHandlerRegistered();\n
+getter Navigator::languages(string);\n
+getter Navigator::language(string);\n
+getter Navigator::mimeTypes(user);\n
+getter Navigator::onLine(boolean);\n
+getter Navigator::plugins(user);\n
+method Navigator::registerContentHandler();\n
+method Navigator::registerProtocolHandler();\n
+method Navigator::unregisterContentHandler();\n
+method Navigator::unregisterProtocolHandler();\n
+method Navigator::yieldForStorageUpdates();\n
+method NodeFilter::acceptNode();\n
+method NodeIterator::detach();\n
+getter NodeIterator::filter(user);\n
+method NodeIterator::nextNode();\n
+getter NodeIterator::pointerBeforeReferenceNode(boolean);\n
+method NodeIterator::previousNode();\n
+getter NodeIterator::referenceNode(user);\n
+getter NodeIterator::root(user);\n
+getter NodeIterator::whatToShow(unsigned long);\n
+getter PageTransitionEvent::persisted(boolean);\n
+method Path2D::addPath();\n
+method Path2D::addPathByStrokingPath();\n
+method Path2D::addPathByStrokingText();\n
+method Path2D::addText();\n
+method Path2D::arc();\n
+method Path2D::arcTo();\n
+method Path2D::bezierCurveTo();\n
+method Path2D::closePath();\n
+method Path2D::ellipse();\n
+method Path2D::lineTo();\n
+method Path2D::moveTo();\n
+method Path2D::quadraticCurveTo();\n
+method Path2D::rect();\n
+method PluginArray::item();\n
+getter PluginArray::length(unsigned long);\n
+method PluginArray::namedItem();\n
+method PluginArray::refresh();\n
+getter Plugin::description(string);\n
+getter Plugin::filename(string);\n
+method Plugin::item();\n
+getter Plugin::length(unsigned long);\n
+method Plugin::namedItem();\n
+getter Plugin::name(string);\n
+getter PopStateEvent::state(any);\n
+getter ProcessingInstruction::sheet(user);\n
+getter ProcessingInstruction::target(string);\n
+getter PseudoElement::cascadedStyle(user);\n
+getter PseudoElement::defaultStyle(user);\n
+getter PseudoElement::rawComputedStyle(user);\n
+getter PseudoElement::usedStyle(user);\n
+getter RadioNodeList::value(string);\n
+setter RadioNodeList::value(string);\n
+method Range::cloneContents();\n
+method Range::cloneRange();\n
+method Range::collapse();\n
+getter Range::collapsed(boolean);\n
+getter Range::commonAncestorContainer(user);\n
+method Range::compareBoundaryPoints();\n
+method Range::comparePoint();\n
+method Range::createContextualFragment();\n
+method Range::deleteContents();\n
+method Range::detach();\n
+getter Range::endContainer(user);\n
+getter Range::endOffset(unsigned long);\n
+method Range::extractContents();\n
+method Range::insertNode();\n
+method Range::intersectsNode();\n
+method Range::isPointInRange();\n
+method Range::selectNode();\n
+method Range::selectNodeContents();\n
+method Range::setEnd();\n
+method Range::setEndAfter();\n
+method Range::setEndBefore();\n
+method Range::setStart();\n
+method Range::setStartAfter();\n
+method Range::setStartBefore();\n
+getter Range::startContainer(user);\n
+getter Range::startOffset(unsigned long);\n
+method Range::surroundContents();\n
+getter RelatedEvent::relatedTarget(user);\n
+getter SharedWorkerGlobalScope::applicationCache(user);\n
+getter SharedWorkerGlobalScope::name(string);\n
+getter SharedWorkerGlobalScope::onconnect(user);\n
+setter SharedWorkerGlobalScope::onconnect(user);\n
+getter SharedWorker::onerror(user);\n
+setter SharedWorker::onerror(user);\n
+getter SharedWorker::port(user);\n
+method Storage::clear();\n
+getter StorageEvent::key(string);\n
+getter StorageEvent::newValue(string);\n
+getter StorageEvent::oldValue(string);\n
+getter StorageEvent::storageArea(user);\n
+getter StorageEvent::url(string);\n
+method Storage::getItem();\n
+method Storage::key();\n
+getter Storage::length(unsigned long);\n
+method Storage::removeItem();\n
+method Storage::setItem();\n
+getter StyleSheet::disabled(boolean);\n
+setter StyleSheet::disabled(boolean);\n
+getter StyleSheet::href(string);\n
+method StyleSheetList::item();\n
+getter StyleSheetList::length(unsigned long);\n
+getter StyleSheet::media(user);\n
+getter StyleSheet::ownerNode(multiple);\n
+getter StyleSheet::parentStyleSheet(user);\n
+getter StyleSheet::title(string);\n
+getter StyleSheet::type(string);\n
+getter SVGElement::style(user);\n
+getter TextMetrics::actualBoundingBoxAscent(double);\n
+getter TextMetrics::actualBoundingBoxDescent(double);\n
+getter TextMetrics::actualBoundingBoxLeft(double);\n
+getter TextMetrics::actualBoundingBoxRight(double);\n
+getter TextMetrics::alphabeticBaseline(double);\n
+getter TextMetrics::emHeightAscent(double);\n
+getter TextMetrics::emHeightDescent(double);\n
+getter TextMetrics::fontBoundingBoxAscent(double);\n
+getter TextMetrics::fontBoundingBoxDescent(double);\n
+getter TextMetrics::hangingBaseline(double);\n
+getter TextMetrics::ideographicBaseline(double);\n
+getter TextMetrics::width(double);\n
+method Text::splitText();\n
+getter TextTrack::activeCues(user);\n
+method TextTrack::addCue();\n
+getter TextTrackCue::endTime(double);\n
+setter TextTrackCue::endTime(double);\n
+getter TextTrackCue::id(string);\n
+setter TextTrackCue::id(string);\n
+method TextTrackCueList::getCueById();\n
+getter TextTrackCueList::length(unsigned long);\n
+getter TextTrackCue::onenter(user);\n
+setter TextTrackCue::onenter(user);\n
+getter TextTrackCue::onexit(user);\n
+setter TextTrackCue::onexit(user);\n
+getter TextTrackCue::pauseOnExit(boolean);\n
+setter TextTrackCue::pauseOnExit(boolean);\n
+getter TextTrackCue::startTime(double);\n
+setter TextTrackCue::startTime(double);\n
+getter TextTrack::cues(user);\n
+getter TextTrackCue::track(user);\n
+getter TextTrack::id(string);\n
+getter TextTrack::inBandMetadataTrackDispatchType(string);\n
+getter TextTrack::kind(user);\n
+getter TextTrack::label(string);\n
+getter TextTrack::language(string);\n
+method TextTrackList::getTrackById();\n
+getter TextTrackList::length(unsigned long);\n
+getter TextTrackList::onaddtrack(user);\n
+setter TextTrackList::onaddtrack(user);\n
+getter TextTrackList::onchange(user);\n
+setter TextTrackList::onchange(user);\n
+getter TextTrackList::onremovetrack(user);\n
+setter TextTrackList::onremovetrack(user);\n
+getter TextTrack::mode(user);\n
+setter TextTrack::mode(user);\n
+getter TextTrack::oncuechange(user);\n
+setter TextTrack::oncuechange(user);\n
+method TextTrack::removeCue();\n
+getter Text::wholeText(string);\n
+method TimeRanges::end();\n
+getter TimeRanges::length(unsigned long);\n
+method TimeRanges::start();\n
+getter Touch::region(string);\n
+getter TrackEvent::track(multiple);\n
+getter TreeWalker::currentNode(user);\n
+setter TreeWalker::currentNode(user);\n
+getter TreeWalker::filter(user);\n
+method TreeWalker::firstChild();\n
+method TreeWalker::lastChild();\n
+method TreeWalker::nextNode();\n
+method TreeWalker::nextSibling();\n
+method TreeWalker::parentNode();\n
+method TreeWalker::previousNode();\n
+method TreeWalker::previousSibling();\n
+getter TreeWalker::root(user);\n
+getter TreeWalker::whatToShow(unsigned long);\n
+getter UIEvent::detail(long);\n
+method UIEvent::initUIEvent();\n
+getter UIEvent::view(user);\n
+method URL::domainToASCII();\n
+method URL::domainToUnicode();\n
+getter URL::hash(user);\n
+setter URL::hash(user);\n
+getter URL::hostname(user);\n
+setter URL::hostname(user);\n
+getter URL::host(user);\n
+setter URL::host(user);\n
+getter URL::href(user);\n
+setter URL::href(user);\n
+getter URL::origin(user);\n
+getter URL::password(user);\n
+setter URL::password(user);\n
+getter URL::pathname(user);\n
+setter URL::pathname(user);\n
+getter URL::port(user);\n
+setter URL::port(user);\n
+getter URL::protocol(user);\n
+setter URL::protocol(user);\n
+method URLSearchParams::append();\n
+method URLSearchParams::delete();\n
+method URLSearchParams::get();\n
+method URLSearchParams::getAll();\n
+method URLSearchParams::has();\n
+method URLSearchParams::set();\n
+getter URL::searchParams(user);\n
+setter URL::searchParams(user);\n
+getter URL::search(user);\n
+setter URL::search(user);\n
+getter URL::username(user);\n
+setter URL::username(user);\n
+getter ValidityState::badInput(boolean);\n
+getter ValidityState::customError(boolean);\n
+getter ValidityState::patternMismatch(boolean);\n
+getter ValidityState::rangeOverflow(boolean);\n
+getter ValidityState::rangeUnderflow(boolean);\n
+getter ValidityState::stepMismatch(boolean);\n
+getter ValidityState::tooLong(boolean);\n
+getter ValidityState::tooShort(boolean);\n
+getter ValidityState::typeMismatch(boolean);\n
+getter ValidityState::valid(boolean);\n
+getter ValidityState::valueMissing(boolean);\n
+getter VideoTrack::id(string);\n
+getter VideoTrack::kind(string);\n
+getter VideoTrack::label(string);\n
+getter VideoTrack::language(string);\n
+method VideoTrackList::getTrackById();\n
+getter VideoTrackList::length(unsigned long);\n
+getter VideoTrackList::onaddtrack(user);\n
+setter VideoTrackList::onaddtrack(user);\n
+getter VideoTrackList::onchange(user);\n
+setter VideoTrackList::onchange(user);\n
+getter VideoTrackList::onremovetrack(user);\n
+setter VideoTrackList::onremovetrack(user);\n
+getter VideoTrackList::selectedIndex(long);\n
+getter VideoTrack::selected(boolean);\n
+setter VideoTrack::selected(boolean);\n
+getter WebSocket::binaryType(user);\n
+setter WebSocket::binaryType(user);\n
+getter WebSocket::bufferedAmount(unsigned long);\n
+method WebSocket::close();\n
+getter WebSocket::extensions(string);\n
+getter WebSocket::onclose(user);\n
+setter WebSocket::onclose(user);\n
+getter WebSocket::onerror(user);\n
+setter WebSocket::onerror(user);\n
+getter WebSocket::onmessage(user);\n
+setter WebSocket::onmessage(user);\n
+getter WebSocket::onopen(user);\n
+setter WebSocket::onopen(user);\n
+getter WebSocket::protocol(string);\n
+getter WebSocket::readyState(unsigned short);\n
+method WebSocket::send();\n
+getter WebSocket::url(string);\n
+getter WheelEvent::deltaMode(unsigned long);\n
+getter WheelEvent::deltaX(double);\n
+getter WheelEvent::deltaY(double);\n
+getter WheelEvent::deltaZ(double);\n
+method WheelEvent::initWheelEvent();\n
+getter Window::applicationCache(user);\n
+method Window::atob();\n
+method Window::blur();\n
+method Window::btoa();\n
+method Window::cancelAnimationFrame();\n
+method Window::captureEvents();\n
+method Window::clearInterval();\n
+method Window::clearTimeout();\n
+method Window::close();\n
+getter Window::closed(boolean);\n
+method Window::confirm();\n
+method Window::createImageBitmap();\n
+getter Window::external(user);\n
+method Window::focus();\n
+getter Window::frameElement(user);\n
+getter Window::frames(user);\n
+method Window::getComputedStyle();\n
+getter Window::history(user);\n
+getter Window::length(unsigned long);\n
+getter Window::localStorage(user);\n
+getter Window::locationbar(user);\n
+getter Window::menubar(user);\n
+getter Window::onabort(user);\n
+setter Window::onabort(user);\n
+getter Window::onafterprint(user);\n
+setter Window::onafterprint(user);\n
+getter Window::onautocompleteerror(user);\n
+setter Window::onautocompleteerror(user);\n
+getter Window::onautocomplete(user);\n
+setter Window::onautocomplete(user);\n
+getter Window::onbeforeprint(user);\n
+setter Window::onbeforeprint(user);\n
+getter Window::onbeforeunload(user);\n
+setter Window::onbeforeunload(user);\n
+getter Window::onblur(user);\n
+setter Window::onblur(user);\n
+getter Window::oncancel(user);\n
+setter Window::oncancel(user);\n
+getter Window::oncanplaythrough(user);\n
+setter Window::oncanplaythrough(user);\n
+getter Window::oncanplay(user);\n
+setter Window::oncanplay(user);\n
+getter Window::onchange(user);\n
+setter Window::onchange(user);\n
+getter Window::onclick(user);\n
+setter Window::onclick(user);\n
+getter Window::onclose(user);\n
+setter Window::onclose(user);\n
+getter Window::oncontextmenu(user);\n
+setter Window::oncontextmenu(user);\n
+getter Window::oncuechange(user);\n
+setter Window::oncuechange(user);\n
+getter Window::ondblclick(user);\n
+setter Window::ondblclick(user);\n
+getter Window::ondragend(user);\n
+setter Window::ondragend(user);\n
+getter Window::ondragenter(user);\n
+setter Window::ondragenter(user);\n
+getter Window::ondragexit(user);\n
+setter Window::ondragexit(user);\n
+getter Window::ondragleave(user);\n
+setter Window::ondragleave(user);\n
+getter Window::ondragover(user);\n
+setter Window::ondragover(user);\n
+getter Window::ondragstart(user);\n
+setter Window::ondragstart(user);\n
+getter Window::ondrag(user);\n
+setter Window::ondrag(user);\n
+getter Window::ondrop(user);\n
+setter Window::ondrop(user);\n
+getter Window::ondurationchange(user);\n
+setter Window::ondurationchange(user);\n
+getter Window::onemptied(user);\n
+setter Window::onemptied(user);\n
+getter Window::onended(user);\n
+setter Window::onended(user);\n
+getter Window::onerror(user);\n
+setter Window::onerror(user);\n
+getter Window::onfocus(user);\n
+setter Window::onfocus(user);\n
+getter Window::onhashchange(user);\n
+setter Window::onhashchange(user);\n
+getter Window::oninput(user);\n
+setter Window::oninput(user);\n
+getter Window::oninvalid(user);\n
+setter Window::oninvalid(user);\n
+getter Window::onkeydown(user);\n
+setter Window::onkeydown(user);\n
+getter Window::onkeypress(user);\n
+setter Window::onkeypress(user);\n
+getter Window::onkeyup(user);\n
+setter Window::onkeyup(user);\n
+getter Window::onlanguagechange(user);\n
+setter Window::onlanguagechange(user);\n
+getter Window::onloadeddata(user);\n
+setter Window::onloadeddata(user);\n
+getter Window::onloadedmetadata(user);\n
+setter Window::onloadedmetadata(user);\n
+getter Window::onloadstart(user);\n
+setter Window::onloadstart(user);\n
+getter Window::onload(user);\n
+setter Window::onload(user);\n
+getter Window::onmessage(user);\n
+setter Window::onmessage(user);\n
+getter Window::onmousedown(user);\n
+setter Window::onmousedown(user);\n
+getter Window::onmouseenter(user);\n
+setter Window::onmouseenter(user);\n
+getter Window::onmouseleave(user);\n
+setter Window::onmouseleave(user);\n
+getter Window::onmousemove(user);\n
+setter Window::onmousemove(user);\n
+getter Window::onmouseout(user);\n
+setter Window::onmouseout(user);\n
+getter Window::onmouseover(user);\n
+setter Window::onmouseover(user);\n
+getter Window::onmouseup(user);\n
+setter Window::onmouseup(user);\n
+getter Window::onoffline(user);\n
+setter Window::onoffline(user);\n
+getter Window::ononline(user);\n
+setter Window::ononline(user);\n
+getter Window::onpagehide(user);\n
+setter Window::onpagehide(user);\n
+getter Window::onpageshow(user);\n
+setter Window::onpageshow(user);\n
+getter Window::onpause(user);\n
+setter Window::onpause(user);\n
+getter Window::onplaying(user);\n
+setter Window::onplaying(user);\n
+getter Window::onplay(user);\n
+setter Window::onplay(user);\n
+getter Window::onpopstate(user);\n
+setter Window::onpopstate(user);\n
+getter Window::onprogress(user);\n
+setter Window::onprogress(user);\n
+getter Window::onratechange(user);\n
+setter Window::onratechange(user);\n
+getter Window::onreset(user);\n
+setter Window::onreset(user);\n
+getter Window::onresize(user);\n
+setter Window::onresize(user);\n
+getter Window::onscroll(user);\n
+setter Window::onscroll(user);\n
+getter Window::onseeked(user);\n
+setter Window::onseeked(user);\n
+getter Window::onseeking(user);\n
+setter Window::onseeking(user);\n
+getter Window::onselect(user);\n
+setter Window::onselect(user);\n
+getter Window::onshow(user);\n
+setter Window::onshow(user);\n
+getter Window::onsort(user);\n
+setter Window::onsort(user);\n
+getter Window::onstalled(user);\n
+setter Window::onstalled(user);\n
+getter Window::onstorage(user);\n
+setter Window::onstorage(user);\n
+getter Window::onsubmit(user);\n
+setter Window::onsubmit(user);\n
+getter Window::onsuspend(user);\n
+setter Window::onsuspend(user);\n
+getter Window::ontimeupdate(user);\n
+setter Window::ontimeupdate(user);\n
+getter Window::ontoggle(user);\n
+setter Window::ontoggle(user);\n
+getter Window::onunload(user);\n
+setter Window::onunload(user);\n
+getter Window::onvolumechange(user);\n
+setter Window::onvolumechange(user);\n
+getter Window::onwaiting(user);\n
+setter Window::onwaiting(user);\n
+getter Window::onwheel(user);\n
+setter Window::onwheel(user);\n
+method Window::open();\n
+getter Window::opener(any);\n
+setter Window::opener(any);\n
+getter Window::parent(user);\n
+getter Window::personalbar(user);\n
+method Window::postMessage();\n
+method Window::print();\n
+method Window::prompt();\n
+method Window::releaseEvents();\n
+method Window::requestAnimationFrame();\n
+getter Window::scrollbars(user);\n
+getter Window::self(user);\n
+getter Window::sessionStorage(user);\n
+method Window::setInterval();\n
+method Window::setTimeout();\n
+method Window::showModalDialog();\n
+getter Window::statusbar(user);\n
+getter Window::status(string);\n
+setter Window::status(string);\n
+method Window::stop();\n
+getter Window::toolbar(user);\n
+getter Window::top(user);\n
+method WorkerGlobalScope::atob();\n
+method WorkerGlobalScope::btoa();\n
+method WorkerGlobalScope::clearInterval();\n
+method WorkerGlobalScope::clearTimeout();\n
+method WorkerGlobalScope::close();\n
+method WorkerGlobalScope::createImageBitmap();\n
+method WorkerGlobalScope::importScripts();\n
+getter WorkerGlobalScope::location(user);\n
+getter WorkerGlobalScope::navigator(user);\n
+getter WorkerGlobalScope::onerror(user);\n
+setter WorkerGlobalScope::onerror(user);\n
+getter WorkerGlobalScope::onlanguagechange(user);\n
+setter WorkerGlobalScope::onlanguagechange(user);\n
+getter WorkerGlobalScope::onoffline(user);\n
+setter WorkerGlobalScope::onoffline(user);\n
+getter WorkerGlobalScope::ononline(user);\n
+setter WorkerGlobalScope::ononline(user);\n
+getter WorkerGlobalScope::self(user);\n
+method WorkerGlobalScope::setInterval();\n
+method WorkerGlobalScope::setTimeout();\n
+getter WorkerLocation::hash(user);\n
+getter WorkerLocation::hostname(user);\n
+getter WorkerLocation::host(user);\n
+getter WorkerLocation::href(user);\n
+getter WorkerLocation::origin(user);\n
+getter WorkerLocation::pathname(user);\n
+getter WorkerLocation::port(user);\n
+getter WorkerLocation::protocol(user);\n
+getter WorkerLocation::search(user);\n
+getter WorkerNavigator::appCodeName(string);\n
+getter WorkerNavigator::appName(string);\n
+getter WorkerNavigator::appVersion(string);\n
+getter WorkerNavigator::languages(string);\n
+getter WorkerNavigator::language(string);\n
+getter WorkerNavigator::onLine(boolean);\n
+getter WorkerNavigator::platform(string);\n
+getter WorkerNavigator::product(string);\n
+getter WorkerNavigator::productSub(string);\n
+method WorkerNavigator::taintEnabled();\n
+getter WorkerNavigator::userAgent(string);\n
+getter WorkerNavigator::vendor(string);\n
+getter WorkerNavigator::vendorSub(string);\n
+getter Worker::onerror(user);\n
+setter Worker::onerror(user);\n
+getter Worker::onmessage(user);\n
+setter Worker::onmessage(user);\n
+method Worker::postMessage();\n
+method Worker::terminate();\n
+method XMLDocument::load();\n
+method XMLSerializer::serializeToString();\n
+*/
diff --git a/Docs/env.sh b/Docs/env.sh
index 83a5219..44c00a4 100644
--- a/Docs/env.sh
+++ b/Docs/env.sh
@@ -80,9 +80,9 @@ NS_BROWSER="netsurf"
case "${HOST}" in
i586-pc-haiku)
# tools required to build the browser for haiku (beos)
- NS_TOOLS=""
+ NS_TOOLS="nsgenbind"
# libraries required for the haiku target abi
- NS_FRONTEND_LIBS=""
+ NS_FRONTEND_LIBS="libsvgtiny"
;;
*arwin*)
# tools required to build the browser for OS X
@@ -161,9 +161,9 @@ ns-yum-install()
# Haiku secondary arch suffix:
# empty for primary (gcc2 on x86),
# "_x86" for gcc4 secondary.
-HA=
+HA=_x86
# Haiku packages
-NS_DEV_HPKG="curl${HA}_devel libpng${HA}_devel jpeg${HA}_devel openssl${HA}_devel
libiconv${HA}_devel expat${HA}_devel pkgconfig${HA} gperf${HA}"
+NS_DEV_HPKG="devel:libcurl${HA} devel:libpng${HA} devel:libjpeg${HA}
devel:libcrypto${HA} devel:libiconv${HA} devel:libexpat${HA} cmd:pkg_config${HA} cmd:gperf
html_parser"
# pkgman commandline to install necessary dev packages
ns-pkgman-install()
@@ -222,7 +222,7 @@ ns-package-install()
# git pull in all repos parameters are passed to git pull
ns-pull()
{
- for REPO in ${NS_BUILDSYSTEM} ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_TOOLS}
${NS_BROWSER} ; do
+ for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS}
${NS_TOOLS} ${NS_BROWSER}) ; do
echo -n " GIT: Pulling ${REPO}: "
if [ -f "${TARGET_WORKSPACE}/${REPO}/.git/config" ]; then
(cd ${TARGET_WORKSPACE}/${REPO} && git pull $*; )
diff --git a/Docs/netsurf-gtk.1 b/Docs/netsurf-gtk.1
index 6043398..7b2f4f4 100644
--- a/Docs/netsurf-gtk.1
+++ b/Docs/netsurf-gtk.1
@@ -7,7 +7,7 @@
.\"
.\"THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
.Dd December 26, 2014
-.Dt NETSURF 1
+.Dt NETSURF 1 CON
.Os
.Sh NAME
.Nm netsurf
diff --git a/Makefile b/Makefile
index 784c42f..ce2a0a6 100644
--- a/Makefile
+++ b/Makefile
@@ -839,8 +839,8 @@ install: all-program install-$(TARGET)
.PHONY: docs
-docs:
- doxygen Docs/Doxyfile
+docs: Docs/Doxyfile
+ doxygen $<
# ----------------------------------------------------------------------------
diff --git a/Makefile.config.example b/Makefile.config.example
index 8737e53..686ffea 100644
--- a/Makefile.config.example
+++ b/Makefile.config.example
@@ -34,3 +34,5 @@
# override NETSURF_USE_MOZJS := NO
# override NETSURF_USE_MOZJS := YES
+### To change flags to javascript binding generator
+# GBFLAGS:=-g
diff --git a/amiga/Makefile.target b/amiga/Makefile.target
index e704eb5..29b3905 100644
--- a/amiga/Makefile.target
+++ b/amiga/Makefile.target
@@ -70,12 +70,13 @@ MESSAGES_FILTER=ami
S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \
misc.c bitmap.c font.c filetype.c utf8.c login.c \
plotters.c object.c menu.c save_pdf.c arexx.c version.c \
- cookies.c context_menu.c clipboard.c help.c font_scan.c \
+ cookies.c ctxmenu.c clipboard.c help.c font_scan.c \
launch.c search.c history_local.c download.c iff_dr2d.c \
sslcert.c gui_options.c print.c theme.c drag.c icon.c libs.c \
datatypes.c dt_picture.c dt_anim.c dt_sound.c plugin_hack.c \
stringview/stringview.c stringview/urlhistory.c rtg.c \
- agclass/amigaguide_class.c os3support.c font_bitmap.c
+ agclass/amigaguide_class.c os3support.c font_bitmap.c \
+ selectmenu.c
S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
# This is the final source build list
diff --git a/amiga/bitmap.h b/amiga/bitmap.h
index f270871..ff1b01c 100755
--- a/amiga/bitmap.h
+++ b/amiga/bitmap.h
@@ -19,6 +19,7 @@
#ifndef AMIGA_BITMAP_H
#define AMIGA_BITMAP_H
+#include <stdbool.h>
#include <exec/types.h>
#include <proto/graphics.h>
#include <intuition/classusr.h>
diff --git a/amiga/clipboard.c b/amiga/clipboard.c
index 7495398..10f0faf 100644
--- a/amiga/clipboard.c
+++ b/amiga/clipboard.c
@@ -327,7 +327,7 @@ void ami_drag_selection(struct gui_window *g)
}
}
-bool ami_easy_clipboard(char *text)
+bool ami_easy_clipboard(const char *text)
{
gui_set_clipboard(text, strlen(text), NULL, 0);
return true;
diff --git a/amiga/clipboard.h b/amiga/clipboard.h
index db6fc35..bc5b779 100755
--- a/amiga/clipboard.h
+++ b/amiga/clipboard.h
@@ -34,7 +34,7 @@ void gui_start_selection(struct gui_window *g);
void ami_clipboard_init(void);
void ami_clipboard_free(void);
void ami_drag_selection(struct gui_window *g);
-bool ami_easy_clipboard(char *text);
+bool ami_easy_clipboard(const char *text);
bool ami_easy_clipboard_bitmap(struct bitmap *bitmap);
#ifdef WITH_NS_SVG
bool ami_easy_clipboard_svg(struct hlcache_handle *c);
diff --git a/amiga/context_menu.c b/amiga/context_menu.c
deleted file mode 100644
index 9a10a25..0000000
--- a/amiga/context_menu.c
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*
- * Copyright 2008 - 2011 Chris Young <chris(a)unsatisfactorysoftware.co.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/>.
- */
-
-#ifdef __amigaos4__
-
-#include <proto/popupmenu.h>
-#include <proto/intuition.h>
-#include <proto/asl.h>
-#include <proto/dos.h>
-#include <proto/exec.h>
-#include <reaction/reaction_macros.h>
-#include <string.h>
-
-#include "utils/nsoption.h"
-#include "utils/utf8.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
-#include "render/form.h"
-#include "desktop/browser_history.h"
-#include "desktop/browser.h"
-#include "desktop/hotlist.h"
-#include "desktop/searchweb.h"
-#include "desktop/textinput.h"
-#include "desktop/gui_window.h"
-
-#include "amiga/clipboard.h"
-#include "amiga/bitmap.h"
-#include "amiga/file.h"
-#include "amiga/filetype.h"
-#include "amiga/gui.h"
-#include "amiga/history_local.h"
-#include "amiga/iff_dr2d.h"
-#include "amiga/plugin_hack.h"
-#include "amiga/theme.h"
-#include "amiga/tree.h"
-#include "amiga/utf8.h"
-#include "amiga/context_menu.h"
-
-
-HOOKF(uint32, ami_context_menu_hook, Object *, item, APTR);
-HOOKF(uint32, ami_popup_hook, Object *, item, APTR);
-
-static bool ami_context_menu_history(const struct browser_window *bw, int x0, int y0,
- int x1, int y1, const struct history_entry *entry, void *user_data);
-
-enum {
- CMID_SELECTFILE,
- CMID_COPYURL,
- CMID_URLOPEN,
- CMID_URLOPENWIN,
- CMID_URLOPENTAB,
- CMID_URLHOTLIST,
- CMID_SAVEURL,
- CMID_SHOWOBJ,
- CMID_COPYOBJ,
- CMID_CLIPOBJ,
- CMID_SAVEOBJ,
- CMID_SAVEIFFOBJ,
- CMID_RELOADOBJ,
- CMID_SELALL,
- CMID_SELCLEAR,
- CMID_SELCUT,
- CMID_SELCOPY,
- CMID_SELPASTE,
- CMID_SELSEARCH,
- CMID_SELSAVE,
- CMID_FRAMEWIN,
- CMID_FRAMETAB,
- CMID_FRAMESHOW,
- CMID_FRAMERELOAD,
- CMID_FRAMECOPYURL,
- CMID_FRAMESAVE,
- CMID_FRAMESAVECOMPLETE,
- CMID_PLUGINCMD,
- CMID_NAVHOME,
- CMID_NAVBACK,
- CMID_NAVFORWARD,
- CMID_NAVRELOAD,
- CMID_NAVSTOP,
- CMID_PAGEOPEN,
- CMID_PAGESAVE,
- CMID_PAGESAVECOMPLETE,
- CMID_PAGEHOTLIST,
- CMID_PAGECLOSE,
-
- CMID_TREE_EXPAND,
- CMID_TREE_COLLAPSE,
- CMID_TREE_LAUNCH,
- CMID_TREE_NEWFOLDER,
- CMID_TREE_NEWITEM,
- CMID_TREE_SETDEFAULT,
- CMID_TREE_CLEARDEFAULT,
- CMID_TREE_DELETE,
- CMID_TREE_EDITTITLE,
- CMID_TREE_EDITLINK,
- CMID_TREE_EDITFOLDER,
- CMID_TREE_ADDHOTLIST,
-
- CMSUB_OBJECT,
- CMSUB_URL,
- CMSUB_SEL,
- CMSUB_PAGE,
- CMSUB_FRAME,
- CMSUB_NAVIGATE,
- CMID_HISTORY,
- CMID_LAST
-};
-
-struct ami_file_input_menu_data {
- int x;
- int y;
- struct browser_window *bw;
-};
-
-struct Library *PopupMenuBase = NULL;
-struct PopupMenuIFace *IPopupMenu = NULL;
-static char *ctxmenulab[CMID_LAST];
-static Object *ctxmenuobj = NULL;
-static struct Hook ctxmenuhook;
-
-void ami_context_menu_init(void)
-{
- if((PopupMenuBase = OpenLibrary("popupmenu.class",0))) {
- IPopupMenu = (struct PopupMenuIFace
*)GetInterface(PopupMenuBase,"main",1,NULL);
- }
-
- ctxmenulab[CMID_SELECTFILE] = ami_utf8_easy((char
*)messages_get("SelectFile"));
-
- ctxmenulab[CMID_SHOWOBJ] = ami_utf8_easy((char *)messages_get("ObjShow"));
- ctxmenulab[CMID_RELOADOBJ] = ami_utf8_easy((char
*)messages_get("ObjReload"));
- ctxmenulab[CMID_COPYOBJ] = ami_utf8_easy((char *)messages_get("CopyURL"));
- ctxmenulab[CMID_CLIPOBJ] = ami_utf8_easy((char *)messages_get("CopyClip"));
- ctxmenulab[CMID_SAVEOBJ] = ami_utf8_easy((char *)messages_get("SaveAs"));
- ctxmenulab[CMID_SAVEIFFOBJ] = ami_utf8_easy((char *)messages_get("SaveIFF"));
-
- ctxmenulab[CMID_PAGEOPEN] = ami_utf8_easy((char *)messages_get("OpenFile"));
- ctxmenulab[CMID_PAGESAVE] = ami_utf8_easy((char *)messages_get("SaveAs"));
- ctxmenulab[CMID_PAGESAVECOMPLETE] = ami_utf8_easy((char
*)messages_get("SaveComplete"));
- ctxmenulab[CMID_PAGEHOTLIST] = ami_utf8_easy((char
*)messages_get("HotlistAdd"));
- ctxmenulab[CMID_PAGECLOSE] = ami_utf8_easy((char *)messages_get("Close"));
-
- ctxmenulab[CMID_FRAMEWIN] = ami_utf8_easy((char
*)messages_get("FrameNewWin"));
- ctxmenulab[CMID_FRAMETAB] = ami_utf8_easy((char
*)messages_get("FrameNewTab"));
- ctxmenulab[CMID_FRAMESHOW] = ami_utf8_easy((char
*)messages_get("FrameOnly"));
- ctxmenulab[CMID_FRAMESAVE] = ami_utf8_easy((char *)messages_get("SaveAs"));
- ctxmenulab[CMID_FRAMESAVECOMPLETE] = ami_utf8_easy((char
*)messages_get("SaveComplete"));
- ctxmenulab[CMID_FRAMECOPYURL] = ami_utf8_easy((char
*)messages_get("CopyURL"));
- ctxmenulab[CMID_FRAMERELOAD] = ami_utf8_easy((char
*)messages_get("ObjReload"));
-
- ctxmenulab[CMID_SAVEURL] = ami_utf8_easy((char *)messages_get("LinkDload"));
- ctxmenulab[CMID_URLOPEN] = ami_utf8_easy((char *)messages_get("Open"));
- ctxmenulab[CMID_URLOPENWIN] = ami_utf8_easy((char
*)messages_get("LinkNewWin"));
- ctxmenulab[CMID_URLOPENTAB] = ami_utf8_easy((char
*)messages_get("LinkNewTab"));
- ctxmenulab[CMID_URLHOTLIST] = ami_utf8_easy((char
*)messages_get("HotlistAdd"));
- ctxmenulab[CMID_COPYURL] = ami_utf8_easy((char *)messages_get("CopyURL"));
-
- ctxmenulab[CMID_NAVHOME] = ami_utf8_easy((char *)messages_get("Home"));
- ctxmenulab[CMID_NAVBACK] = ami_utf8_easy((char *)messages_get("Back"));
- ctxmenulab[CMID_NAVFORWARD] = ami_utf8_easy((char *)messages_get("Forward"));
- ctxmenulab[CMID_NAVRELOAD] = ami_utf8_easy((char
*)messages_get("ObjReload"));
- ctxmenulab[CMID_NAVSTOP] = ami_utf8_easy((char *)messages_get("Stop"));
-
- ctxmenulab[CMID_SELCUT] = ami_utf8_easy((char *)messages_get("CutNS"));
- ctxmenulab[CMID_SELCOPY] = ami_utf8_easy((char *)messages_get("CopyNS"));
- ctxmenulab[CMID_SELPASTE] = ami_utf8_easy((char *)messages_get("PasteNS"));
- ctxmenulab[CMID_SELALL] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
- ctxmenulab[CMID_SELCLEAR] = ami_utf8_easy((char *)messages_get("ClearNS"));
- ctxmenulab[CMID_SELSEARCH] = ami_utf8_easy((char
*)messages_get("SearchWeb"));
- ctxmenulab[CMID_SELSAVE] = ami_utf8_easy((char *)messages_get("SaveAs"));
-
- ctxmenulab[CMID_PLUGINCMD] = ami_utf8_easy((char
*)messages_get("ExternalApp"));
-
- ctxmenulab[CMSUB_PAGE] = ami_utf8_easy((char *)messages_get("Page"));
- ctxmenulab[CMSUB_FRAME] = ami_utf8_easy((char *)messages_get("Frame"));
- ctxmenulab[CMSUB_OBJECT] = ami_utf8_easy((char *)messages_get("Object"));
- ctxmenulab[CMSUB_NAVIGATE] = ami_utf8_easy((char *)messages_get("Navigate"));
- ctxmenulab[CMSUB_URL] = ami_utf8_easy((char *)messages_get("Link"));
- ctxmenulab[CMSUB_SEL] = ami_utf8_easy((char *)messages_get("Selection"));
-
- /* Back button */
- ctxmenulab[CMID_HISTORY] = ami_utf8_easy((char
*)messages_get("HistLocalNS"));
-
- /* treeviews */
- ctxmenulab[CMID_TREE_EXPAND] = ami_utf8_easy((char *)messages_get("Expand"));
- ctxmenulab[CMID_TREE_COLLAPSE] = ami_utf8_easy((char
*)messages_get("Collapse"));
- ctxmenulab[CMID_TREE_LAUNCH] = ami_utf8_easy((char
*)messages_get("TreeLaunch"));
- ctxmenulab[CMID_TREE_NEWFOLDER] = ami_utf8_easy((char
*)messages_get("TreeNewFolder"));
- ctxmenulab[CMID_TREE_NEWITEM] = ami_utf8_easy((char
*)messages_get("TreeNewLink"));
- ctxmenulab[CMID_TREE_SETDEFAULT] = ami_utf8_easy((char
*)messages_get("TreeDefault"));
- ctxmenulab[CMID_TREE_CLEARDEFAULT] = ami_utf8_easy((char
*)messages_get("TreeClear"));
- ctxmenulab[CMID_TREE_DELETE] = ami_utf8_easy((char
*)messages_get("TreeDelete"));
- ctxmenulab[CMID_TREE_EDITTITLE] = ami_utf8_easy((char
*)messages_get("EditTitle"));
- ctxmenulab[CMID_TREE_EDITLINK] = ami_utf8_easy((char
*)messages_get("EditLink"));
- ctxmenulab[CMID_TREE_EDITFOLDER] = ami_utf8_easy((char
*)messages_get("EditFolder"));
- ctxmenulab[CMID_TREE_ADDHOTLIST] = ami_utf8_easy((char
*)messages_get("HotlistAdd"));
-
-}
-
-static void ami_context_menu_add_submenu(Object *ctxmenuobj, ULONG cmsub, void
*userdata)
-{
- /*
- * CMSUB_PAGE - userdata = hlcache_object *
- * CMSUB_FRAME - userdata = hlcache_object *
- * CMSUB_URL - userdata = char *
- * CMSUB_OBJECT - userdata = hlcache_object *
- * CMSUB_SEL - userdata = gui_window * (only for menu construction)
- * CMSUB_NAVIGATE - userdata = browser_window *
- * CMID_SELECTFILE - userdata = ami_file_input_menu_data *
- */
-
- struct gui_window *gw = NULL;
-
- switch(cmsub)
- {
- case CMSUB_PAGE:
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_PAGE],
- PMSIMPLESUB,
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PAGEOPEN],
- PMIA_ID, CMID_PAGEOPEN,
- PMIA_UserData, userdata,
- PMIA_CommKey, "O",
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PAGESAVE],
- PMIA_ID, CMID_PAGESAVE,
- PMIA_UserData, userdata,
- PMIA_CommKey, "S",
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PAGESAVECOMPLETE],
- PMIA_ID, CMID_PAGESAVECOMPLETE,
- PMIA_UserData, userdata,
- PMIA_Disabled, (content_get_type(userdata) != CONTENT_HTML),
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PAGECLOSE],
- PMIA_ID, CMID_PAGECLOSE,
- PMIA_UserData, userdata,
- PMIA_CommKey, "K",
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PAGEHOTLIST],
- PMIA_ID, CMID_PAGEHOTLIST,
- PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)),
- PMIA_CommKey, "B",
- TAG_DONE),
- PMEND,
- TAG_DONE),
- ~0);
- break;
-
- case CMSUB_FRAME:
- IDoMethod(ctxmenuobj,PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_FRAME],
- PMSIMPLESUB,
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMEWIN],
- PMIA_ID, CMID_FRAMEWIN,
- PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMETAB],
- PMIA_ID, CMID_FRAMETAB,
- PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESHOW],
- PMIA_ID, CMID_FRAMESHOW,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMERELOAD],
- PMIA_ID, CMID_FRAMERELOAD,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMECOPYURL],
- PMIA_ID, CMID_FRAMECOPYURL,
- PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)),
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESAVE],
- PMIA_ID, CMID_FRAMESAVE,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESAVECOMPLETE],
- PMIA_ID, CMID_FRAMESAVECOMPLETE,
- PMIA_UserData, userdata,
- PMIA_Disabled, (content_get_type(userdata) != CONTENT_HTML),
- TAG_DONE),
- PMEND,
- TAG_DONE),
- ~0);
- break;
-
- case CMSUB_NAVIGATE:
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_NAVIGATE],
- PMSIMPLESUB,
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_NAVHOME],
- PMIA_ID, CMID_NAVHOME,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_NAVBACK],
- PMIA_ID, CMID_NAVBACK,
- PMIA_UserData, userdata,
- PMIA_Disabled, !browser_window_back_available(userdata),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_NAVFORWARD],
- PMIA_ID, CMID_NAVFORWARD,
- PMIA_UserData, userdata,
- PMIA_Disabled, !browser_window_forward_available(userdata),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_NAVRELOAD],
- PMIA_ID, CMID_NAVRELOAD,
- PMIA_UserData, userdata,
- PMIA_CommKey, "R",
- PMIA_Disabled, !browser_window_reload_available(userdata),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_NAVSTOP],
- PMIA_ID, CMID_NAVSTOP,
- PMIA_UserData, userdata,
- PMIA_Disabled, !browser_window_stop_available(userdata),
- TAG_DONE),
- PMEND,
- TAG_DONE),
- ~0);
- break;
-
- case CMSUB_URL:
- IDoMethod(ctxmenuobj,PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_URL],
- PMSIMPLESUB,
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPEN],
- PMIA_ID, CMID_URLOPEN,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENWIN],
- PMIA_ID, CMID_URLOPENWIN,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENTAB],
- PMIA_ID, CMID_URLOPENTAB,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_COPYURL],
- PMIA_ID, CMID_COPYURL,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_URLHOTLIST],
- PMIA_ID, CMID_URLHOTLIST,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEURL],
- PMIA_ID, CMID_SAVEURL,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMEND,
- TAG_DONE),
- ~0);
- break;
-
- case CMSUB_OBJECT:
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_OBJECT],
- PMSIMPLESUB,
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SHOWOBJ],
- PMIA_ID, CMID_SHOWOBJ,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_RELOADOBJ],
- PMIA_ID, CMID_RELOADOBJ,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_COPYOBJ],
- PMIA_ID, CMID_COPYOBJ,
- PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)),
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_CLIPOBJ],
- PMIA_ID, CMID_CLIPOBJ,
- PMIA_UserData, userdata,
- PMIA_Disabled, (content_get_type(userdata) != CONTENT_IMAGE),
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEOBJ],
- PMIA_ID, CMID_SAVEOBJ,
- PMIA_UserData, userdata,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEIFFOBJ],
- PMIA_ID, CMID_SAVEIFFOBJ,
- PMIA_UserData, userdata,
- PMIA_Disabled, (content_get_type(userdata) != CONTENT_IMAGE),
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_PLUGINCMD],
- PMIA_ID, CMID_PLUGINCMD,
- PMIA_UserData, userdata,
- PMIA_Disabled, !ami_mime_content_to_cmd(userdata),
- TAG_DONE),
- PMEND,
- TAG_DONE),
- ~0);
- break;
-
- case CMSUB_SEL:
- gw = userdata;
- BOOL disabled_noselection = !(browser_window_get_editor_flags(gw->bw) &
BW_EDITOR_CAN_COPY);
-
- IDoMethod(ctxmenuobj,PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMSUB_SEL],
- PMIA_SubMenu, NewObject(POPUPMENU_GetClass(), NULL,
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELCUT],
- PMIA_ID,CMID_SELCUT,
- PMIA_Disabled, !(browser_window_get_editor_flags(gw->bw) &
BW_EDITOR_CAN_CUT),
- PMIA_CommKey, "X",
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELCOPY],
- PMIA_ID,CMID_SELCOPY,
- PMIA_Disabled, disabled_noselection,
- PMIA_CommKey, "C",
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELPASTE],
- PMIA_ID,CMID_SELPASTE,
- PMIA_Disabled, (gw->c_h == 0),
- PMIA_CommKey, "V",
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELALL],
- PMIA_ID,CMID_SELALL,
- PMIA_CommKey, "A",
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELCLEAR],
- PMIA_ID,CMID_SELCLEAR,
- PMIA_Disabled, disabled_noselection,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELSEARCH],
- PMIA_ID,CMID_SELSEARCH,
- PMIA_Disabled, disabled_noselection,
- TAG_DONE),
- PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELSAVE],
- PMIA_ID,CMID_SELSAVE,
- PMIA_Disabled, disabled_noselection,
- TAG_DONE),
- TAG_DONE),
- TAG_DONE),
- ~0);
- break;
-
- case CMID_SELECTFILE:
- IDoMethod(ctxmenuobj,PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_SELECTFILE],
- PMIA_ID, CMID_SELECTFILE,
- PMIA_UserData, userdata,
- TAG_DONE),
- ~0);
- break;
- }
-}
-
-void ami_context_menu_free(void)
-{
- int i;
-
- if(ctxmenuobj) DisposeObject(ctxmenuobj);
-
- for(i=0;i<CMID_LAST;i++)
- {
- ami_utf8_free(ctxmenulab[i]);
- }
-
- if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu);
- if(PopupMenuBase) CloseLibrary(PopupMenuBase);
-}
-
-BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap)
-{
- if(nsoption_bool(context_menu) == false) return FALSE;
-
- if((nsoption_bool(kiosk_mode) == false) && (trap == FALSE))
- {
- if(browser_window_back_available(gwin->gw->bw) &&
- ami_gadget_hit(gwin->objects[GID_BACK],
- gwin->win->MouseX, gwin->win->MouseY))
- trap = TRUE;
-
- if(browser_window_forward_available(gwin->gw->bw) &&
- ami_gadget_hit(gwin->objects[GID_FORWARD],
- gwin->win->MouseX, gwin->win->MouseY))
- trap = TRUE;
- }
-
- if(gwin->rmbtrapped == trap) return trap;
-
- SetWindowAttr(gwin->win, WA_RMBTrap, (APTR)(ULONG)trap, sizeof(BOOL));
- gwin->rmbtrapped = trap;
-
- return trap;
-}
-
-void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
-{
- struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw);
- bool no_more_menus = false;
- bool menuhascontent = false;
- struct browser_window_features ccdata;
-
- if(!cc) return;
- if(ctxmenuobj) DisposeObject(ctxmenuobj);
-
- ctxmenuhook.h_Entry = ami_context_menu_hook;
- ctxmenuhook.h_SubEntry = NULL;
- ctxmenuhook.h_Data = gwin;
-
- ctxmenuobj = NewObject( POPUPMENU_GetClass(), NULL,
- PMA_MenuHandler, &ctxmenuhook,
- TAG_DONE);
-
- if(gwin->gw->bw && ami_gadget_hit(gwin->objects[GID_BACK],
- gwin->win->MouseX, gwin->win->MouseY))
- {
- gwin->temp = 0;
- browser_window_history_enumerate_back(gwin->gw->bw, ami_context_menu_history,
gwin);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_HISTORY],
- PMIA_ID, CMID_HISTORY,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
-
- menuhascontent = true;
- }
- else if(gwin->gw->bw && ami_gadget_hit(gwin->objects[GID_FORWARD],
- gwin->win->MouseX, gwin->win->MouseY))
- {
- gwin->temp = 0;
- browser_window_history_enumerate_forward(gwin->gw->bw, ami_context_menu_history,
gwin);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_HISTORY],
- PMIA_ID, CMID_HISTORY,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
-
- menuhascontent = true;
- }
- else
- {
- if(no_more_menus == false)
- {
- browser_window_get_features(gwin->gw->bw, x, y, &ccdata);
-
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_PAGE, cc);
- menuhascontent = true;
-
- if(ccdata.main && (ccdata.main != cc))
- {
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_FRAME, ccdata.main);
- menuhascontent = true;
- }
-
- if(ccdata.link)
- {
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_URL, (char
*)nsurl_access(ccdata.link));
- menuhascontent = true;
- }
-
- if(ccdata.object)
- {
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_OBJECT, ccdata.object);
- menuhascontent = true;
- }
-
- if(ccdata.form_features == CTX_FORM_FILE)
- {
- struct ami_file_input_menu_data file_input = {
- .x = x,
- .y = y,
- .bw = gwin->gw->bw
- };
- ami_context_menu_add_submenu(ctxmenuobj, CMID_SELECTFILE, &file_input);
- menuhascontent = true;
- }
-
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_NAVIGATE, gwin->gw->bw);
- menuhascontent = true;
-
- if(browser_window_can_select(gwin->gw->bw))
- {
- ami_context_menu_add_submenu(ctxmenuobj, CMSUB_SEL, gwin->gw);
- menuhascontent = true;
- }
- }
- }
-
- if(!menuhascontent) return;
-
- gui_window_set_pointer(gwin->gw, GUI_POINTER_DEFAULT);
-
- IDoMethod(ctxmenuobj, PM_OPEN, gwin->win);
-}
-
-HOOKF(uint32, ami_context_menu_hook, Object *, item, APTR)
-{
- int32 itemid = 0;
- struct gui_window_2 *gwin = hook->h_Data;
- APTR userdata = NULL;
- struct browser_window *bw;
- struct hlcache_handle *object;
- struct bitmap *bm;
- nsurl *url;
- nserror error;
-
- if(GetAttrs(item, PMIA_ID, &itemid,
- PMIA_UserData, &userdata,
- TAG_DONE)) {
- switch(itemid)
- {
- case CMID_SELECTFILE:
- if(AslRequestTags(filereq,
- ASLFR_Window, gwin->win,
- ASLFR_SleepWindow, TRUE,
- ASLFR_TitleText,messages_get("NetSurf"),
- ASLFR_Screen,scrn,
- ASLFR_DoSaveMode,FALSE,
- TAG_DONE))
- {
- struct ami_file_input_menu_data
- *file_input = userdata;
- char fname[1024];
-
- strlcpy(fname,filereq->fr_Drawer,1024);
- AddPart(fname,filereq->fr_File,1024);
-
- browser_window_drop_file_at_point(
- file_input->bw,
- file_input->x,
- file_input->y,
- fname);
- }
- break;
-
- case CMID_PAGEOPEN:
- ami_file_open(gwin);
- break;
-
- case CMID_PAGECLOSE:
- browser_window_destroy(gwin->gw->bw);
- break;
-
- case CMID_URLHOTLIST:
- case CMID_PAGEHOTLIST:
- {
- if (nsurl_create(userdata, &url) != NSERROR_OK)
- break;
-
- hotlist_add_url(url);
- nsurl_unref(url);
- ami_gui_update_hotlist_button(gwin);
- }
- break;
-
- case CMID_FRAMECOPYURL:
- case CMID_COPYURL:
- case CMID_COPYOBJ:
- ami_easy_clipboard((char *)userdata);
- break;
-
- case CMID_FRAMEWIN:
- case CMID_URLOPENWIN:
- error = nsurl_create(userdata, &url);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
- url,
- browser_window_get_url(gwin->gw->bw),
- gwin->gw->bw,
- &bw);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
- }
-
-
- break;
-
- case CMID_FRAMETAB:
- case CMID_URLOPENTAB:
- error = nsurl_create(userdata, &url);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY | BW_CREATE_TAB,
- url,
- browser_window_get_url(gwin->gw->bw),
- gwin->gw->bw,
- &bw);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
- }
-
- break;
-
- case CMID_FRAMESAVE:
- case CMID_SAVEURL:
- {
- nsurl *url;
- if (nsurl_create(userdata, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
- } else {
- browser_window_navigate(gwin->gw->bw,
- url,
- browser_window_get_url(gwin->gw->bw),
- BW_NAVIGATE_DOWNLOAD,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- }
- break;
-
- case CMID_FRAMESHOW:
- case CMID_SHOWOBJ:
- browser_window_navigate(gwin->gw->bw,
- hlcache_handle_get_url(userdata),
- browser_window_get_url(gwin->gw->bw),
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
-
- break;
-
- case CMID_URLOPEN:
- {
- nsurl *url;
- if (nsurl_create(userdata, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
- } else {
- browser_window_navigate(gwin->gw->bw,
- url,
- browser_window_get_url(gwin->gw->bw),
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- }
- break;
-
- case CMID_FRAMERELOAD:
- case CMID_RELOADOBJ:
- object = (struct hlcache_handle *)userdata;
- content_invalidate_reuse_data(object);
- browser_window_reload(gwin->gw->bw, false);
- break;
-
- case CMID_CLIPOBJ:
- object = (struct hlcache_handle *)userdata;
- if((bm = content_get_bitmap(object)))
- {
- bm->url = (char *)nsurl_access(hlcache_handle_get_url(object));
- bm->title = (char *)content_get_title(object);
- ami_easy_clipboard_bitmap(bm);
- }
-#ifdef WITH_NS_SVG
- else if(ami_mime_compare(object, "svg") == true)
- {
- ami_easy_clipboard_svg(object);
- }
-#endif
- break;
-
- case CMID_SAVEOBJ:
- case CMID_PAGESAVE:
- ami_file_save_req(AMINS_SAVE_SOURCE, gwin,
- (struct hlcache_handle *)userdata);
- break;
-
- case CMID_PAGESAVECOMPLETE:
- case CMID_FRAMESAVECOMPLETE:
- ami_file_save_req(AMINS_SAVE_COMPLETE, gwin,
- (struct hlcache_handle *)userdata);
- break;
-
- case CMID_SAVEIFFOBJ:
- ami_file_save_req(AMINS_SAVE_IFF, gwin,
- (struct hlcache_handle *)userdata);
- break;
-
- case CMID_PLUGINCMD:
- amiga_plugin_hack_execute((struct hlcache_handle *)userdata);
- break;
-
- case CMID_HISTORY:
- if(userdata == NULL)
- {
- ami_history_open(gwin->gw);
- }
- else
- {
- browser_window_history_go(gwin->gw->bw,
- (struct history_entry *)userdata, false);
- }
- break;
-
- case CMID_NAVHOME:
- {
- nsurl *url;
-
- if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
- } else {
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
-
- }
- break;
-
- case CMID_NAVBACK:
- ami_gui_history(gwin, true);
- break;
-
- case CMID_NAVFORWARD:
- ami_gui_history(gwin, false);
- break;
-
- case CMID_NAVSTOP:
- if(browser_window_stop_available(gwin->gw->bw))
- browser_window_stop(gwin->gw->bw);
- break;
-
- case CMID_NAVRELOAD:
- if(browser_window_reload_available(gwin->gw->bw))
- browser_window_reload(gwin->gw->bw, true);
- break;
-
- case CMID_SELCUT:
- browser_window_key_press(gwin->gw->bw, NS_KEY_CUT_SELECTION);
- break;
-
- case CMID_SELCOPY:
- browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION);
- browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
- break;
-
- case CMID_SELPASTE:
- browser_window_key_press(gwin->gw->bw, NS_KEY_PASTE);
- break;
-
- case CMID_SELALL:
- browser_window_key_press(gwin->gw->bw, NS_KEY_SELECT_ALL);
- gui_start_selection(gwin->gw);
- break;
-
- case CMID_SELCLEAR:
- browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
- break;
-
- case CMID_SELSAVE:
- ami_file_save_req(AMINS_SAVE_SELECTION, gwin, NULL);
- break;
-
- case CMID_SELSEARCH:
- {
- char *sel;
-
- if((sel = browser_window_get_selection(gwin->gw->bw)))
- {
- nserror ret;
- nsurl *url;
-
- ret = search_web_omni(sel, SEARCH_WEB_OMNI_SEARCHONLY, &url);
- free(sel);
- if (ret == NSERROR_OK) {
- ret = browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
- }
- }
- }
- break;
- }
- }
-
- return itemid;
-}
-
-#if 0
-/* \todo This is the context menu for the treeviews which needs fixing */
-static uint32 ami_context_menu_hook_tree(struct Hook *hook, Object *item, APTR reserved)
-{
- int32 itemid = 0;
- struct tree *tree = hook->h_Data;
- APTR userdata = NULL;
-
- if(GetAttrs(item,PMIA_ID, &itemid,
- PMIA_UserData, &userdata,
- TAG_DONE))
- {
- switch(itemid)
- {
- case CMID_TREE_LAUNCH:
- tree_keypress(tree, NS_KEY_CR);
- break;
-
- case CMID_TREE_EDITFOLDER:
- hotlist_edit_selection();
- break;
-
- case CMID_TREE_EDITTITLE:
- warn_user("TODO.", 0);
- break;
-
- case CMID_TREE_EDITLINK:
- warn_user("TODO.", 0);
- break;
-
- case CMID_TREE_NEWFOLDER:
- hotlist_add_folder(NULL, false, 0);
- break;
-
- case CMID_TREE_NEWITEM:
- hotlist_add_entry(NULL, NULL, false, 0);
- break;
-
- case CMID_TREE_SETDEFAULT:
- warn_user("TODO.", 0);
- break;
-
- case CMID_TREE_CLEARDEFAULT:
- warn_user("TODO.", 0);
- break;
-
- case CMID_TREE_ADDHOTLIST:
- warn_user("TODO.", 0);
- break;
-
- case CMID_TREE_DELETE:
- tree_keypress(tree, NS_KEY_DELETE_RIGHT);
- break;
- }
- }
- return itemid;
-}
-
-void ami_context_menu_show_tree(struct tree *tree, struct Window *win, int type)
-{
- struct node *root = tree_get_root(tree);
- struct node *sel_node = tree_get_selected_node(root);
- bool has_selection = tree_node_has_selection(root);
- bool menu_content = false;
-
- if(ctxmenuobj) DisposeObject(ctxmenuobj);
-
- ctxmenuhook.h_Entry = ami_context_menu_hook_tree;
- ctxmenuhook.h_SubEntry = NULL;
- ctxmenuhook.h_Data = tree;
-
- ctxmenuobj = NewObject( POPUPMENU_GetClass(), NULL,
- PMA_MenuHandler, &ctxmenuhook,
- TAG_DONE);
-
- if(has_selection && (type != AMI_TREE_COOKIES) &&
- ((sel_node == NULL) ||
- (tree_node_is_folder(sel_node) == false))) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_LAUNCH],
- PMIA_ID, CMID_TREE_LAUNCH,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
-
- menu_content = true;
- }
-
- if(type == AMI_TREE_HOTLIST) {
- if(menu_content == true) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
-
- menu_content = false;
- }
-
- if(has_selection && (sel_node != NULL)) {
- if(tree_node_is_folder(sel_node) == true) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITFOLDER],
- PMIA_ID, CMID_TREE_EDITFOLDER,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
- }
- else
- {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITTITLE],
- PMIA_ID, CMID_TREE_EDITTITLE,
- PMIA_UserData, sel_node,
- TAG_DONE),
- ~0);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITLINK],
- PMIA_ID, CMID_TREE_EDITLINK,
- PMIA_UserData, sel_node,
- TAG_DONE),
- ~0);
- }
- menu_content = true;
- }
-
- if(menu_content == true) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
-
- menu_content = false;
- }
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_NEWFOLDER],
- PMIA_ID, CMID_TREE_NEWFOLDER,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_NEWITEM],
- PMIA_ID, CMID_TREE_NEWITEM,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
-
- if(has_selection && (sel_node != NULL) &&
- (tree_node_is_folder(sel_node) == true)) {
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
-
- if(tree_node_is_default(sel_node) == true)
- {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_CLEARDEFAULT],
- PMIA_ID, CMID_TREE_CLEARDEFAULT,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
- }
- else
- {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_SETDEFAULT],
- PMIA_ID, CMID_TREE_SETDEFAULT,
- PMIA_UserData, NULL,
- TAG_DONE),
- ~0);
- }
- }
-
- menu_content = true;
- }
-
- if((type == AMI_TREE_HISTORY) && has_selection &&
- (sel_node != NULL) && (tree_node_is_folder(sel_node) == false)) {
- if(menu_content == true) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
- }
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_ADDHOTLIST],
- PMIA_ID, CMID_TREE_ADDHOTLIST,
- PMIA_UserData, sel_node,
- TAG_DONE),
- ~0);
-
- menu_content = true;
- }
-
- if(has_selection) {
- if(menu_content == true) {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, ~0,
- TAG_DONE),
- ~0);
- }
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_DELETE],
- PMIA_ID, CMID_TREE_DELETE,
- PMIA_UserData, root,
- TAG_DONE),
- ~0);
-
- menu_content = true;
- }
-
- if(menu_content == true)
- IDoMethod(ctxmenuobj, PM_OPEN, win);
-}
-#endif
-
-static bool ami_context_menu_history(const struct browser_window *bw,
- int x0, int y0, int x1, int y1,
- const struct history_entry *entry, void *user_data)
-{
- struct gui_window_2 *gwin = (struct gui_window_2 *)user_data;
-
- gwin->temp++;
- if(gwin->temp > 10) return false;
-
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject(POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)browser_window_history_entry_get_title(entry),
- PMIA_ID, CMID_HISTORY,
- PMIA_UserData, entry,
- TAG_DONE),
- ~0);
-
- return true;
-}
-
-HOOKF(uint32, ami_popup_hook, Object *, item, APTR)
-{
- uint32 itemid = 0;
- struct gui_window *gwin = hook->h_Data;
-
- if(GetAttr(PMIA_ID, item, &itemid))
- {
- form_select_process_selection(gwin->shared->control,itemid);
- }
-
- return itemid;
-}
-
-void gui_create_form_select_menu(struct gui_window *g,
- struct form_control *control)
-{
- /* TODO: PMIA_Title memory leaks as we don't free the strings.
- * We use the core menu anyway, but in future when popupmenu.class
- * improves we will probably start using this again.
- */
-
- struct gui_window *gwin = g;
- struct form_option *opt = form_select_get_option(control, 0);
- ULONG i = 0;
-
- if(ctxmenuobj) DisposeObject(ctxmenuobj);
-
- ctxmenuhook.h_Entry = ami_popup_hook;
- ctxmenuhook.h_SubEntry = NULL;
- ctxmenuhook.h_Data = gwin;
-
- gwin->shared->control = control;
-
- ctxmenuobj = PMMENU(ami_utf8_easy(form_control_get_name(control))),
- PMA_MenuHandler, &ctxmenuhook, End;
-
- while(opt)
- {
- IDoMethod(ctxmenuobj, PM_INSERT,
- NewObject( POPUPMENU_GetItemClass(), NULL,
- PMIA_Title, (ULONG)ami_utf8_easy(opt->text),
- PMIA_ID, i,
- PMIA_CheckIt, TRUE,
- PMIA_Checked, opt->selected,
- TAG_DONE),
- ~0);
-
- opt = opt->next;
- i++;
- }
-
- gui_window_set_pointer(gwin, GUI_POINTER_DEFAULT); // Clear the menu-style pointer
-
- IDoMethod(ctxmenuobj, PM_OPEN, gwin->shared->win);
-}
-
-#else
-
-#include <proto/dos.h>
-#include "amiga/context_menu.h"
-
-void ami_context_menu_init(void)
-{
-}
-
-void ami_context_menu_free(void)
-{
-}
-
-BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap)
-{
- return FALSE;
-}
-
-void ami_context_menu_show(struct gui_window_2 *gwin, int x, int y)
-{
-}
-
-void gui_create_form_select_menu(struct gui_window *g, struct form_control *control)
-{
-}
-#endif
-
diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c
new file mode 100644
index 0000000..42d0da3
--- /dev/null
+++ b/amiga/ctxmenu.c
@@ -0,0 +1,557 @@
+/*
+ * Copyright 2015 Chris Young <chris(a)unsatisfactorysoftware.co.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
+ * Intuition-based context menu operations
+ */
+
+#ifdef __amigaos4__
+#include <string.h>
+
+#include <proto/exec.h>
+#include <proto/intuition.h>
+
+#include <proto/bitmap.h>
+#include <images/bitmap.h>
+#include <proto/window.h>
+#include <classes/window.h>
+
+#include <intuition/menuclass.h>
+#include <reaction/reaction_macros.h>
+
+#include "amiga/bitmap.h"
+#include "amiga/clipboard.h"
+#include "amiga/ctxmenu.h"
+#include "amiga/filetype.h"
+#include "amiga/gui.h"
+#include "amiga/libs.h"
+#include "amiga/plugin_hack.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+#include "desktop/browser.h"
+#include "desktop/browser_history.h"
+#include "desktop/mouse.h"
+#include "desktop/textinput.h"
+
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+
+enum {
+ AMI_CTX_ID_NONE = 0,
+
+ /* Text selection */
+ AMI_CTX_ID_SELCOPY,
+
+ /* Links */
+ AMI_CTX_ID_URLOPENTAB,
+ AMI_CTX_ID_URLOPENWIN,
+ AMI_CTX_ID_URLDOWNLOAD,
+ AMI_CTX_ID_URLCOPY,
+
+ /* Objects */
+ AMI_CTX_ID_OBJSHOW,
+ AMI_CTX_ID_OBJCOPY,
+ AMI_CTX_ID_OBJCMD,
+
+ /* Frames */
+ AMI_CTX_ID_FRAMESHOW,
+
+ /* History */
+ AMI_CTX_ID_HISTORY,
+ AMI_CTX_ID_HISTORY0,
+ AMI_CTX_ID_HISTORY9F = AMI_CTX_ID_HISTORY0 + 19,
+
+ /* Tabs */
+ AMI_CTX_ID_TABNEW,
+
+ AMI_CTX_ID_MAX
+};
+
+static Object *ctxmenu_obj = NULL;
+
+static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX];
+static char *ctxmenu_item_label[AMI_CTX_ID_MAX];
+static char *ctxmenu_item_shortcut[AMI_CTX_ID_MAX];
+static Object *ctxmenu_item_image[AMI_CTX_ID_MAX];
+
+/****************************
+ * Menu item hook functions *
+ ****************************/
+
+/** Menu functions - called automatically by RA_HandleInput **/
+HOOKF(void, ami_ctxmenu_item_selcopy, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin = (struct gui_window_2 *)hook->h_Data;
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION);
+ browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
+}
+
+HOOKF(void, ami_ctxmenu_item_urlopentab, APTR, window, struct IntuiMessage *)
+{
+ struct browser_window *bw;
+ nsurl *url = (nsurl *)hook->h_Data;
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY |
BW_CREATE_TAB,
+ url,
+ browser_window_get_url(gwin->gw->bw),
+ gwin->gw->bw,
+ &bw);
+
+ if (error != NSERROR_OK)
+ warn_user(messages_get_errorcode(error), 0);
+}
+
+HOOKF(void, ami_ctxmenu_item_urlopenwin, APTR, window, struct IntuiMessage *)
+{
+ struct browser_window *bw;
+ nsurl *url = (nsurl *)hook->h_Data;
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
+ url,
+ browser_window_get_url(gwin->gw->bw),
+ gwin->gw->bw,
+ &bw);
+
+ if (error != NSERROR_OK)
+ warn_user(messages_get_errorcode(error), 0);
+}
+
+HOOKF(void, ami_ctxmenu_item_urldownload, APTR, window, struct IntuiMessage *)
+{
+ nsurl *url = (nsurl *)hook->h_Data;
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ browser_window_get_url(gwin->gw->bw),
+ BW_NAVIGATE_DOWNLOAD,
+ NULL,
+ NULL,
+ NULL);
+}
+
+HOOKF(void, ami_ctxmenu_item_urlcopy, APTR, window, struct IntuiMessage *)
+{
+ nsurl *url = (nsurl *)hook->h_Data;
+ ami_easy_clipboard(nsurl_access(url));
+}
+
+HOOKF(void, ami_ctxmenu_item_objshow, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_navigate(gwin->gw->bw,
+ hlcache_handle_get_url(hook->h_Data),
+ browser_window_get_url(gwin->gw->bw),
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+}
+
+HOOKF(void, ami_ctxmenu_item_objcopy, APTR, window, struct IntuiMessage *)
+{
+ struct bitmap *bm;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ struct hlcache_handle *object = (struct hlcache_handle *)hook->h_Data;
+ if((bm = content_get_bitmap(object)))
+ {
+ bm->url = (char *)nsurl_access(hlcache_handle_get_url(object));
+ bm->title = (char *)content_get_title(object);
+ ami_easy_clipboard_bitmap(bm);
+ }
+#ifdef WITH_NS_SVG
+ else if(ami_mime_compare(object, "svg") == true)
+ {
+ ami_easy_clipboard_svg(object);
+ }
+#endif
+}
+
+HOOKF(void, ami_ctxmenu_item_objcmd, APTR, window, struct IntuiMessage *)
+{
+ amiga_plugin_hack_execute((struct hlcache_handle *)hook->h_Data);
+}
+
+HOOKF(void, ami_ctxmenu_item_frameshow, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_navigate(gwin->gw->bw,
+ hlcache_handle_get_url(hook->h_Data),
+ browser_window_get_url(gwin->gw->bw),
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+}
+
+/** Hooks for clicktab context menu entries **/
+HOOKF(void, ami_ctxmenu_item_tabnew, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ ami_gui_new_blank_tab(gwin);
+}
+
+/** Hook for history context menu entries **/
+HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_history_go(gwin->gw->bw, (struct history_entry *)hook->h_Data,
false);
+}
+
+
+/*************************
+ * Browser context menus *
+ *************************/
+
+/** Add an initialised item to a context menu **/
+static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data)
+{
+ ctxmenu_item_hook[id].h_Data = data;
+
+ IDoMethod(root_menu, OM_ADDMEMBER, MStrip,
+ MA_Type, T_ITEM,
+ MA_ID, id,
+ MA_Label, ctxmenu_item_label[id],
+ MA_Key, ctxmenu_item_shortcut[id],
+ MA_Image, ctxmenu_item_image[id],
+ MA_UserData, &ctxmenu_item_hook[id],
+ MEnd);
+}
+
+/** Hook function called by Intuition, creates context menu structure **/
+static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct
ContextMenuMsg *msg)
+{
+ Object *root_menu;
+ bool ctxmenu_has_content = false;
+ struct gui_window_2 *gwin = hook->h_Data;
+ struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw);
+ struct browser_window_features ccdata;
+ int mx = window->MouseX;
+ int my = window->MouseY;
+ int x, y;
+
+ if(msg->State != CM_QUERY) return 0;
+ if(nsoption_bool(kiosk_mode) == true) return 0;
+// check window is active
+
+ if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj);
+
+ ctxmenu_obj = MStrip,
+ MA_Type, T_ROOT,
+ MA_AddChild, root_menu = MStrip,
+ MA_Type, T_MENU,
+ MA_Label, NULL, //"NetSurf",
+ MA_EmbeddedKey, FALSE,
+ MA_FreeImage, FALSE,
+ MEnd,
+ MEnd;
+
+ if(ami_mouse_to_ns_coords(gwin, &x, &y, mx, my) == false) {
+ /* Outside browser render area */
+ return 0;
+ }
+
+ browser_window_get_features(gwin->gw->bw, x, y, &ccdata);
+
+ if((browser_window_can_select(gwin->gw->bw)) &&
+ ((browser_window_get_editor_flags(gwin->gw->bw) & BW_EDITOR_CAN_COPY))) {
+
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_SELCOPY, gwin);
+
+ ctxmenu_has_content = true;
+ }
+
+ if(ccdata.link) {
+ if(ctxmenu_has_content == true)
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL);
+
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENTAB, ccdata.link);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENWIN, ccdata.link);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLDOWNLOAD, ccdata.link);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLCOPY, ccdata.link);
+ ctxmenu_has_content = true;
+ }
+
+ if(ccdata.object) {
+ if(ctxmenu_has_content == true)
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL);
+
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJSHOW, ccdata.object);
+
+ if(content_get_type(ccdata.object) == CONTENT_IMAGE)
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJCOPY, ccdata.object);
+
+ if(ami_mime_content_to_cmd(ccdata.object))
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJCMD, ccdata.object);
+
+ ctxmenu_has_content = true;
+ }
+
+ if(ccdata.main && (ccdata.main != cc)) {
+ if(ctxmenu_has_content == true)
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL);
+
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_FRAMESHOW, ccdata.main);
+
+ ctxmenu_has_content = true;
+ }
+
+ if(ctxmenu_has_content == true) {
+ msg->Menu = ctxmenu_obj;
+ ami_set_pointer(gwin, GUI_POINTER_DEFAULT, false);
+ }
+
+ return 0;
+}
+
+/** Initial menu item creation **/
+static void ami_ctxmenu_alloc_item(int id, const char *label, const char *key, const char
*image, void *func)
+{
+ if(label == ML_SEPARATOR) {
+ ctxmenu_item_label[id] = ML_SEPARATOR;
+ } else {
+ ctxmenu_item_label[id] = ami_utf8_easy(messages_get(label));
+ }
+
+ if(key != NULL) {
+ ctxmenu_item_shortcut[id] = strdup(key);
+ } else {
+ ctxmenu_item_shortcut[id] = NULL;
+ }
+
+ if(image != NULL) {
+ ctxmenu_item_image[id] = BitMapObj,
+ BITMAP_Screen, scrn,
+ BITMAP_SourceFile, image,
+ BITMAP_Masking, TRUE,
+ BitMapEnd;
+
+ SetAttrs(ctxmenu_item_image[id],
+ BITMAP_Width, 16,
+ BITMAP_Height, 16,
+ TAG_DONE);
+ }
+
+ ctxmenu_item_hook[id].h_Entry = func;
+ ctxmenu_item_hook[id].h_Data = 0;
+}
+
+/** Exported interface documented in ctxmenu.h **/
+struct Hook *ami_ctxmenu_get_hook(APTR data)
+{
+ return AllocSysObjectTags(ASOT_HOOK,
+ ASOHOOK_Entry, (HOOKFUNC)ami_ctxmenu_hook_func,
+ ASOHOOK_Data, data,
+ TAG_DONE);
+}
+
+/** Exported interface documented in ctxmenu.h **/
+void ami_ctxmenu_release_hook(struct Hook *hook)
+{
+ FreeSysObject(ASOT_HOOK, hook);
+}
+
+/** Exported interface documented in ctxmenu.h **/
+void ami_ctxmenu_free(void)
+{
+ for(int i = 1; i < AMI_CTX_ID_MAX; i++) {
+ if((ctxmenu_item_label[i] != NULL) && (ctxmenu_item_label[i] != ML_SEPARATOR))
{
+ ami_utf8_free(ctxmenu_item_label[i]);
+ }
+ ctxmenu_item_label[i] = NULL;
+
+ if(ctxmenu_item_shortcut[i] != NULL) {
+ free(ctxmenu_item_shortcut[i]);
+ ctxmenu_item_shortcut[i] = NULL;
+ }
+
+ if(ctxmenu_item_image[i] != NULL) {
+ DisposeObject(ctxmenu_item_image[i]);
+ ctxmenu_item_image[i] = NULL;
+ }
+ }
+
+ if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj);
+ ctxmenu_obj = NULL;
+}
+
+/** Exported interface documented in ctxmenu.h **/
+void ami_ctxmenu_init(void)
+{
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_NONE, ML_SEPARATOR, NULL, NULL, NULL);
+
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_SELCOPY,
"CopyNS", "C", "TBImages:list_copy",
+ ami_ctxmenu_item_selcopy);
+
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB,
"LinkNewTab", NULL, "TBImages:list_tab",
+ ami_ctxmenu_item_urlopentab);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN,
"LinkNewWin", NULL, "TBImages:list_app",
+ ami_ctxmenu_item_urlopenwin);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLDOWNLOAD,
"LinkDload", NULL, "TBImages:list_save",
+ ami_ctxmenu_item_urldownload);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_URLCOPY,
"CopyURL", NULL, "TBImages:list_copy",
+ ami_ctxmenu_item_urlcopy);
+
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJSHOW,
"ObjShow", NULL, "TBImages:list_preview",
+ ami_ctxmenu_item_objshow);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCOPY,
"CopyClip", NULL, "TBImages:list_copy",
+ ami_ctxmenu_item_objcopy);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCMD,
"ExternalApp", NULL, "TBImages:list_tool",
+ ami_ctxmenu_item_objcmd);
+
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW,
"FrameOnly", NULL, "TBImages:list_preview",
+ ami_ctxmenu_item_frameshow);
+
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T",
"TBImages:list_add",
+ ami_ctxmenu_item_tabnew);
+}
+
+/********************************
+ * History button context menus *
+ ********************************/
+
+/** Create menu entries from browser history **/
+static bool ami_ctxmenu_history(int direction, struct gui_window_2 *gwin, const struct
history_entry *entry)
+{
+ Object *history_root;
+ int id = AMI_CTX_ID_HISTORY0 + gwin->temp;
+ if(direction == AMI_CTXMENU_HISTORY_FORWARD) id += 10;
+
+ if(gwin->temp >= 10) return false;
+
+ ctxmenu_item_hook[id].h_Entry = (HOOKFUNC)ami_ctxmenu_item_history;
+ ctxmenu_item_hook[id].h_Data = (APTR)entry;
+
+ history_root = (Object *)IDoMethod(gwin->history_ctxmenu[direction], MM_FINDID, 0,
AMI_CTX_ID_HISTORY);
+
+ IDoMethod(history_root, OM_ADDMEMBER, MStrip,
+ MA_Type, T_ITEM,
+ MA_Label, browser_window_history_entry_get_title(entry),
+ MA_ID, id,
+ MA_Image, NULL,
+ MA_UserData, &ctxmenu_item_hook[id],
+ MEnd);
+
+ gwin->temp++;
+
+ return true;
+}
+
+/** Callback for browser_window_history_enumerate **/
+static bool ami_ctxmenu_history_back(const struct browser_window *bw,
+ int x0, int y0, int x1, int y1,
+ const struct history_entry *entry, void *user_data)
+{
+ return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_BACK, (struct gui_window_2 *)user_data,
entry);
+}
+
+/** Callback for browser_window_history_enumerate **/
+static bool ami_ctxmenu_history_forward(const struct browser_window *bw,
+ int x0, int y0, int x1, int y1,
+ const struct history_entry *entry, void *user_data)
+{
+ return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_FORWARD, (struct gui_window_2
*)user_data, entry);
+}
+
+/** Exported interface documented in ctxmenu.h **/
+struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin)
+{
+ Object *obj;
+
+ if(gwin->history_ctxmenu[direction] == NULL) {
+ if(ctxmenu_item_label[AMI_CTX_ID_HISTORY] == NULL)
+ ctxmenu_item_label[AMI_CTX_ID_HISTORY] =
ami_utf8_easy(messages_get("History"));
+
+ gwin->history_ctxmenu[direction] = MStrip,
+ MA_Type, T_ROOT,
+ MA_AddChild, MStrip,
+ MA_Type, T_MENU,
+ MA_ID, AMI_CTX_ID_HISTORY,
+ MA_Label, ctxmenu_item_label[AMI_CTX_ID_HISTORY],
+ MA_EmbeddedKey, FALSE,
+ //MA_FreeImage, FALSE,
+ MEnd,
+ MEnd;
+ } else {
+ for (int i = 0; i < 20; i++) {
+ obj = (Object *)IDoMethod(gwin->history_ctxmenu[direction],
+ MM_FINDID, 0, AMI_CTX_ID_HISTORY0 + i);
+ if(obj != NULL) IDoMethod(gwin->history_ctxmenu[direction], OM_REMMEMBER, obj);
+ }
+
+ gwin->temp = 0;
+
+ if(direction == AMI_CTXMENU_HISTORY_BACK) {
+ browser_window_history_enumerate_back(gwin->gw->bw, ami_ctxmenu_history_back,
gwin);
+ } else {
+ browser_window_history_enumerate_forward(gwin->gw->bw,
ami_ctxmenu_history_forward, gwin);
+ }
+ }
+
+ return (struct Menu *)gwin->history_ctxmenu[direction];
+}
+
+
+/**************************
+ * ClickTab context menus *
+ **************************/
+
+/** Exported interface documented in ctxmenu.h **/
+struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin)
+{
+ Object *root_menu;
+
+ if(gwin->clicktab_ctxmenu != NULL) return (struct Menu *)gwin->clicktab_ctxmenu;
+
+ gwin->clicktab_ctxmenu = MStrip,
+ MA_Type, T_ROOT,
+ MA_AddChild, root_menu = MStrip,
+ MA_Type, T_MENU,
+ MA_Label, NULL,
+ MA_EmbeddedKey, FALSE,
+ MEnd,
+ MEnd;
+
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABNEW, gwin);
+
+ return (struct Menu *)gwin->clicktab_ctxmenu;
+}
+
+
+#endif
+
diff --git a/amiga/ctxmenu.h b/amiga/ctxmenu.h
new file mode 100644
index 0000000..08a5fe5
--- /dev/null
+++ b/amiga/ctxmenu.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Chris Young <chris(a)unsatisfactorysoftware.co.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
+ * Interface to Intuition-based context menu operations
+ */
+
+#ifndef AMIGA_CTXMENU_H
+#define AMIGA_CTXMENU_H 1
+struct Hook;
+struct Menu;
+struct gui_window_2;
+
+enum {
+ AMI_CTXMENU_HISTORY_BACK = 0,
+ AMI_CTXMENU_HISTORY_FORWARD = 1
+};
+
+#ifdef __amigaos4__
+/**
+ * Initialise context menus code (allocate label text, etc)
+ * Must be called *after* NetSurf's screen pointer is obtained.
+ */
+void ami_ctxmenu_init(void);
+
+/**
+ * Cleanup context menus code
+ */
+void ami_ctxmenu_free(void);
+
+/**
+ * Get a Hook for WA_ContextMenuHook
+ *
+ * \param data ptr for the hook to use (struct gui_window_2 *)
+ * \returns pointer to a struct Hook
+ */
+struct Hook *ami_ctxmenu_get_hook(APTR data);
+
+/**
+ * Release a Hook for WA_ContextMenuHook
+ *
+ * \param hook ptr to hook
+ */
+void ami_ctxmenu_release_hook(struct Hook *hook);
+
+/**
+ * Create history context menu
+ * The first time this is run it will create an empty menu,
+ * Subsequent runs will (re-)populate with the history.
+ * This is to allow the pointer to be obtained before the browser_window is opened.
+ *
+ * \param direction AMI_CTXMENU_HISTORY_(BACK|FORWARD)
+ * \param gwin struct gui_window_2 *
+ * \returns pointer to menu (for convenience, is also stored in gwin structure)
+ * The returned pointer MUST be disposed of with DisposeObject before program exit.
+ */
+struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin);
+
+/**
+ * Create ClickTab context menu
+ *
+ * \param gwin struct gui_window_2 *
+ * \returns pointer to menu (for convenience, is also stored in gwin structure)
+ * The returned pointer MUST be disposed of with DisposeObject before program exit.
+ */
+struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin);
+
+#else //__amigaos4__
+inline void ami_ctxmenu_init(void) {}
+inline void ami_ctxmenu_free(void) {}
+inline struct Hook *ami_ctxmenu_get_hook(APTR data) {return NULL;}
+inline void ami_ctxmenu_release_hook(struct Hook *hook) {}
+inline struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin)
{return NULL;}
+inline struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin) {return
NULL;}
+#endif //__amigaos4__
+#endif //AMIGA_CTXMENU_H
+
diff --git a/amiga/dist/NetSurf.guide b/amiga/dist/NetSurf.guide
index aecdb18..5db267a 100755
--- a/amiga/dist/NetSurf.guide
+++ b/amiga/dist/NetSurf.guide
@@ -63,35 +63,44 @@ Project Browser Edit @{"Hotlist" link Hotlist}
@{"ARexx" link arexx}
@node Prefs-General "Prefs - General"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Display "Prefs - Display"
@toc Prefs
+@remark todo
+@{"Themes" link Themes}
@endnode
@node Prefs-Connection "Prefs - Connection"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Rendering "Prefs - Rendering"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Fonts "Prefs - Fonts"
@toc Prefs
+@remark todo
See @{"Fonts" link Fonts}
@endnode
@node Prefs-Cache "Prefs - Cache"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Tabs "Prefs - Tabs"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Advanced "Prefs - Advanced"
@toc Prefs
+@remark todo
@endnode
@node Prefs-Export "Prefs - Export"
@@ -323,7 +332,7 @@ The Installer script will set the MIMETYPE tooltype on basic relevant
default fi
2. The icon ENVARC:Sys/def_<filetype> contains the MIMETYPE tooltype.
@endnode
-@node Keyboard Controls "Keyboard"
+@node Keyboard "Keyboard Controls"
This is a list of the keyboard shortcuts used in NetSurf
- RAmiga + R or F5 (reload the current page)
@@ -362,22 +371,22 @@ Keyboard shortcuts used in NetSurf menu
@node Speed "Optimising for speed"
There are a number of options which can be changed that will affect the speed of
NetSurf's rendering. Here are a list of the fastest settings which may help decrease
rendering time on slower platforms:
-@{lindent 2}* Ensure NetSurf is running on a @{b}32-bit screen@{ub} if possible. NetSurf
down-converts from 32-bit ARGB for display, which can impact performance.@{lindent}
+@{lindent 2}* Ensure NetSurf is running on a @{b}32-bit screen@{ub} if possible. NetSurf
down-converts from 32-bit ARGB for display, which can impact performance.@{lindent 0}
-@{lindent 2}* In preferences, General tab, enable @{b}Fast scrolling@{ub}.@{lindent}
+@{lindent 2}* In preferences, General tab, enable @{b}Fast scrolling@{ub}.@{lindent 0}
@{lindent 2}* In preferences, Rendering tab set:
@{b}Cache native versions@{ub} to @{b}Scaled@{ub} (or preferably @{b}All@{ub}, but this
will use more graphics mem, and scaling images is a bigger performance hit)
-Deselect @{b}Higher quality scaling@{ub}, this will be very slow if not done in
hardware.@{lindent}
+Deselect @{b}Higher quality scaling@{ub}, this will be very slow if not done in
hardware.@{lindent 0}
-@{lindent 2}* In @{"Options" link Options}, increase redraw_tile_size_x/y
(increasing this value uses more graphics mem)@{lindent}
+@{lindent 2}* In @{"Options" link Options}, increase redraw_tile_size_x/y
(increasing this value uses more graphics mem)@{lindent 0}
-@{lindent 2}* In @{"Options" link Options}, set font_antialiasing:0@{lindent}
+@{lindent 2}* In @{"Options" link Options}, set font_antialiasing:0@{lindent
0}
@endnode
@node contact "Credits"
NetSurf was ported to AmigaOS 4 by Chris Young
-chris(a)unsatisfactorysoftware.co.uk
+chris\(a)unsatisfactorysoftware.co.uk
The pointer images, AISS theme icon and Throbber were drawn by Martin 'Mason'
Merz.
http://www.masonicons.de
@@ -387,5 +396,5 @@ The default theme icon was adapted from the NetSurf logo by Marko K.
Sepp
All other code and files are the same for all platforms and credited in the files and/or
on the NetSurf website.
http://www.netsurf-browser.org
-The source code can be obtained from
http://source.netsurf-browser.org or (in the event
the service is unavailable) chris(a)unsatisfactorysoftware.co.uk or any other of the NetSurf
developers.
+The source code can be obtained from
http://source.netsurf-browser.org or (in the event
the service is unavailable) chris\(a)unsatisfactorysoftware.co.uk or any other of the
NetSurf developers.
@endnode
diff --git a/amiga/font.c b/amiga/font.c
index c39b002..7569bb6 100644
--- a/amiga/font.c
+++ b/amiga/font.c
@@ -71,6 +71,9 @@
struct ami_font_node
{
+#ifdef __amigaos4__
+ struct SkipNode skip_node;
+#endif
struct OutlineFont *font;
char *bold;
char *italic;
@@ -145,12 +148,16 @@ const uint16 sc_table[] = {
#endif
0, 0};
-
+#ifdef __amigaos4__
+struct SkipList *ami_font_list = NULL;
+#else
struct MinList *ami_font_list = NULL;
+#endif
struct List ami_diskfontlib_list;
lwc_string *glypharray[0xffff + 1];
ULONG ami_devicedpi;
ULONG ami_xdpi;
+static struct Hook ami_font_cache_hook;
static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont, struct RastPort *rp,
uint16 *char1, uint16 *char2, uint32 x, uint32 y, uint32 emwidth, bool aa);
@@ -158,7 +165,6 @@ static inline int32 ami_font_width_glyph(struct OutlineFont *ofont,
const uint16 *char1, const uint16 *char2, uint32 emwidth);
static struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle,
const uint16 *codepoint);
-static void ami_font_cleanup(struct MinList *ami_font_list);
static inline ULONG ami_font_unicode_width(const char *string, ULONG length,
const plot_font_style_t *fstyle, ULONG x, ULONG y, bool aa);
@@ -362,28 +368,41 @@ static inline bool amiga_nsfont_split(const plot_font_style_t
*fstyle,
/**
* Search for a font in the list and load from disk if not present
*/
-static struct ami_font_node *ami_font_open(const char *font)
+static struct ami_font_node *ami_font_open(const char *font, bool critical)
{
- struct nsObject *node;
- struct ami_font_node *nodedata;
+ struct ami_font_node *nodedata = NULL;
- node = (struct nsObject *)FindIName((struct List *)ami_font_list, font);
- if(node)
- {
- nodedata = node->objstruct;
+#ifdef __amigaos4__
+ nodedata = (struct ami_font_node *)FindSkipNode(ami_font_list, (APTR)font);
+#else
+ struct nsObject *node = (struct nsObject *)FindIName((struct List *)ami_font_list,
font);
+ if(node) nodedata = node->objstruct;
+#endif
+
+ if(nodedata) {
GetSysTime(&nodedata->lastused);
return nodedata;
}
LOG("Font cache miss: %s", font);
+#ifdef __amigaos4__
+ nodedata = (struct ami_font_node *)InsertSkipNode(ami_font_list, (APTR)font,
sizeof(struct ami_font_node));
+#else
nodedata = AllocVecTagList(sizeof(struct ami_font_node), NULL);
- nodedata->font = OpenOutlineFont(font, &ami_diskfontlib_list, OFF_OPEN);
+#endif
+ if(nodedata == NULL) {
+ warn_user("NoMemory", "");
+ return NULL;
+ }
+
+ nodedata->font = OpenOutlineFont(font, &ami_diskfontlib_list, OFF_OPEN);
+
if(!nodedata->font)
{
LOG("Requested font not found: %s", font);
- warn_user("CompError", font);
+ if(critical == true) warn_user("CompError", font);
FreeVec(nodedata);
return NULL;
}
@@ -408,12 +427,13 @@ static struct ami_font_node *ami_font_open(const char *font)
GetSysTime(&nodedata->lastused);
+#ifndef __amigaos4__
node = AddObject(ami_font_list, AMINS_FONT);
- if(node)
- {
+ if(node) {
node->objstruct = nodedata;
node->dtz_Node.ln_Name = strdup(font);
}
+#endif
return nodedata;
}
@@ -429,6 +449,7 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
const uint16 *codepoint)
{
struct ami_font_node *node;
+ struct ami_font_node *designed_node = NULL;
struct OutlineFont *ofont;
char *fontname;
ULONG ysize;
@@ -471,7 +492,7 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
break;
}
- node = ami_font_open(fontname);
+ node = ami_font_open(fontname, true);
if(!node) return NULL;
if (fstyle->flags & FONTF_OBLIQUE)
@@ -486,13 +507,9 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
switch(tstyle)
{
case NSA_ITALIC:
- if(node->italic)
- {
- node = ami_font_open(node->italic);
- if(!node) return NULL;
- }
- else
- {
+ if(node->italic) designed_node = ami_font_open(node->italic, false);
+
+ if(designed_node == NULL) {
shearsin = NSA_VALUE_SHEARSIN;
shearcos = NSA_VALUE_SHEARCOS;
}
@@ -504,13 +521,9 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
break;
case NSA_BOLD:
- if(node->bold)
- {
- node = ami_font_open(node->bold);
- if(!node) return NULL;
- }
- else
- {
+ if(node->bold) designed_node = ami_font_open(node->bold, false);
+
+ if(designed_node == NULL) {
emboldenx = NSA_VALUE_BOLDX;
emboldeny = NSA_VALUE_BOLDY;
}
@@ -520,26 +533,18 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
shearsin = NSA_VALUE_SHEARSIN;
shearcos = NSA_VALUE_SHEARCOS;
- if(node->bold)
- {
- node = ami_font_open(node->bold);
- if(!node) return NULL;
- }
- else
- {
+ if(node->bold) designed_node = ami_font_open(node->bold, false);
+
+ if(designed_node == NULL) {
emboldenx = NSA_VALUE_BOLDX;
emboldeny = NSA_VALUE_BOLDY;
}
break;
case NSA_BOLDITALIC:
- if(node->bolditalic)
- {
- node = ami_font_open(node->bolditalic);
- if(!node) return NULL;
- }
- else
- {
+ if(node->bolditalic) designed_node = ami_font_open(node->bolditalic, false);
+
+ if(designed_node == NULL) {
emboldenx = NSA_VALUE_BOLDX;
emboldeny = NSA_VALUE_BOLDY;
shearsin = NSA_VALUE_SHEARSIN;
@@ -551,7 +556,12 @@ static struct OutlineFont *ami_open_outline_font(const
plot_font_style_t *fstyle
/* Scale to 16.16 fixed point */
ysize = fstyle->size * ((1 << 16) / FONT_SIZE_SCALE);
- ofont = node->font;
+ if(designed_node == NULL) {
+ ofont = node->font;
+ } else {
+ ofont = designed_node->font;
+ }
+
#ifndef __amigaos4__
struct BulletBase *BulletBase = ofont->BulletBase;
#endif
@@ -595,17 +605,17 @@ static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont,
struct RastPo
}
#endif
- if(aa == true) {
#ifdef __amigaos4__
+ if(__builtin_expect(aa == true, 1)) {
glyphmaptag = OT_GlyphMap8Bit;
template_type = BLITT_ALPHATEMPLATE;
-#endif
} else {
+#endif
glyphmaptag = OT_GlyphMap;
#ifdef __amigaos4__
template_type = BLITT_TEMPLATE;
-#endif
}
+#endif
long_char_1 = amiga_nsfont_decode_surrogate(char1);
long_char_2 = amiga_nsfont_decode_surrogate(char2);
@@ -638,11 +648,20 @@ static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont,
struct RastPo
BLITA_SrcBytesPerRow, glyph->glm_BMModulo,
TAG_DONE);
#else
- BltTemplate(glyphbm + (glyph->glm_BMModulo * glyph->glm_BlackTop),
- glyph->glm_BlackLeft, glyph->glm_BMModulo, rp,
- x - glyph->glm_X0 + glyph->glm_BlackLeft,
- y - glyph->glm_Y0 + glyph->glm_BlackTop,
- glyph->glm_BlackWidth, glyph->glm_BlackHeight);
+ /* On OS3 the glyph needs to be in chip RAM */
+ void *chip_glyph = AllocVec(glyph->glm_BMModulo * glyph->glm_BMRows,
MEMF_CHIP);
+ if(chip_glyph != NULL) {
+ CopyMem(glyphbm, chip_glyph, glyph->glm_BMModulo * glyph->glm_BMRows);
+
+ BltTemplate(chip_glyph + (glyph->glm_BMModulo * glyph->glm_BlackTop) +
+ ((glyph->glm_BlackLeft >> 4) << 1),
+ glyph->glm_BlackLeft & 0xF, glyph->glm_BMModulo, rp,
+ x - glyph->glm_X0 + glyph->glm_BlackLeft,
+ y - glyph->glm_Y0 + glyph->glm_BlackTop,
+ glyph->glm_BlackWidth, glyph->glm_BlackHeight);
+
+ FreeVec(chip_glyph);
+ }
#endif
}
@@ -677,6 +696,7 @@ static inline int32 ami_font_width_glyph(struct OutlineFont *ofont,
struct GlyphWidthEntry *gwnode;
bool skip_c2 = false;
uint32 long_char_1 = 0;
+ uint32 long_char_2;
#ifndef __amigaos4__
struct BulletBase *BulletBase = ofont->BulletBase;
#endif
@@ -713,9 +733,10 @@ static inline int32 ami_font_width_glyph(struct OutlineFont *ofont,
kern = 0;
if(!skip_c2) {
+ long_char_2 = amiga_nsfont_decode_surrogate(char2);
if(ESetInfo(AMI_OFONT_ENGINE,
- OT_GlyphCode, *char1,
- OT_GlyphCode2, *char2,
+ OT_GlyphCode, long_char_1,
+ OT_GlyphCode2, long_char_2,
TAG_END) == OTERR_Success)
{
EObtainInfo(AMI_OFONT_ENGINE,
@@ -892,34 +913,39 @@ void ami_font_savescanner(void)
ami_font_scan_save(nsoption_charp(font_unicode_file), glypharray);
}
-void ami_init_fonts(void)
+#ifdef __amigaos4__
+static LONG ami_font_cache_sort(struct Hook *hook, APTR key1, APTR key2)
{
- /* Initialise Unicode font scanner */
- ami_font_initscanner(false, true);
-
- /* Initialise font caching etc lists */
- ami_font_list = NewObjList();
- NewList(&ami_diskfontlib_list);
-
- /* run first cleanup in ten minutes */
- ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list);
+ return stricmp(key1, key2);
}
+#endif
-void ami_close_fonts(void)
+#ifdef __amigaos4__
+static void ami_font_cleanup(struct SkipList *skiplist)
{
- LOG("Cleaning up font cache");
- FreeObjList(ami_font_list);
- ami_font_list = NULL;
- ami_font_finiscanner();
-}
+ struct ami_font_node *node;
+ struct ami_font_node *nnode;
+ struct TimeVal curtime;
-void ami_font_close(struct ami_font_node *node)
-{
- /* Called from FreeObjList if node type is AMINS_FONT */
+ node = (struct ami_font_node *)GetFirstSkipNode(skiplist);
+ if(node == NULL) return;
- CloseOutlineFont(node->font, &ami_diskfontlib_list);
-}
+ do {
+ nnode = (struct ami_font_node *)GetNextSkipNode(skiplist, (struct SkipNode *)node);
+ GetSysTime(&curtime);
+ SubTime(&curtime, &node->lastused);
+ if(curtime.Seconds > 300)
+ {
+ LOG("Freeing %s not used for %ld seconds", node->skip_node.sn_Key,
curtime.Seconds);
+ ami_font_close(node);
+ RemoveSkipNode(skiplist, node->skip_node.sn_Key);
+ }
+ } while((node = nnode));
+ /* reschedule to run in five minutes */
+ ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list);
+}
+#else
static void ami_font_cleanup(struct MinList *ami_font_list)
{
struct nsObject *node;
@@ -947,6 +973,66 @@ static void ami_font_cleanup(struct MinList *ami_font_list)
/* reschedule to run in five minutes */
ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list);
}
+#endif
+
+void ami_init_fonts(void)
+{
+ /* Initialise Unicode font scanner */
+ ami_font_initscanner(false, true);
+
+ /* Initialise font caching etc lists */
+#ifdef __amigaos4__
+ ami_font_cache_hook.h_Entry = (HOOKFUNC)ami_font_cache_sort;
+ ami_font_cache_hook.h_Data = 0;
+ ami_font_list = CreateSkipList(&ami_font_cache_hook, 8);
+#else
+ ami_font_list = NewObjList();
+#endif
+
+ NewList(&ami_diskfontlib_list);
+
+ /* run first cleanup in ten minutes */
+ ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list);
+}
+
+#ifdef __amigaos4__
+static void ami_font_del_skiplist(struct SkipList *skiplist)
+{
+ struct SkipNode *node;
+ struct SkipNode *nnode;
+
+ node = GetFirstSkipNode(skiplist);
+ if(node == NULL) return;
+
+ do {
+ nnode = GetNextSkipNode(skiplist, node);
+ ami_font_close((struct ami_font_node *)node);
+
+ } while((node = nnode));
+
+ DeleteSkipList(skiplist);
+}
+#endif
+
+void ami_close_fonts(void)
+{
+ LOG("Cleaning up font cache");
+ ami_schedule(-1, (void *)ami_font_cleanup, ami_font_list);
+#ifdef __amigaos4__
+ ami_font_del_skiplist(ami_font_list);
+#else
+ FreeObjList(ami_font_list);
+#endif
+ ami_font_list = NULL;
+ ami_font_finiscanner();
+}
+
+void ami_font_close(struct ami_font_node *node)
+{
+ /* Called from FreeObjList if node type is AMINS_FONT */
+
+ CloseOutlineFont(node->font, &ami_diskfontlib_list);
+}
void ami_font_setdevicedpi(int id)
{
diff --git a/amiga/font_scan.c b/amiga/font_scan.c
index 4f4b774..b65798d 100644
--- a/amiga/font_scan.c
+++ b/amiga/font_scan.c
@@ -215,7 +215,7 @@ static void ami_font_scan_gui_close(struct ami_font_scan_window *fsw)
static ULONG ami_font_scan_font(const char *fontname, lwc_string **glypharray)
{
struct OutlineFont *ofont;
- struct MinList *widthlist;
+ struct MinList *widthlist = NULL;
struct GlyphWidthEntry *gwnode;
ULONG foundglyphs = 0;
lwc_error lerror;
@@ -482,6 +482,7 @@ void ami_font_scan_init(const char *filename, bool force_scan, bool
save,
found = ami_font_scan_load(filename, glypharray);
if(found == 0) {
+ LOG("Creating new font glyph cache");
if((list = NewObjList())) {
/* add preferred fonts list */
diff --git a/amiga/gui.c b/amiga/gui.c
index 8280d30..a24942b 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2014 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2015 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf,
http://www.netsurf-browser.org/
*
@@ -34,9 +34,6 @@
#include <proto/intuition.h>
#include <proto/keymap.h>
#include <proto/locale.h>
-#ifdef __amigaos4__
-#include <proto/popupmenu.h>
-#endif
#include <proto/utility.h>
#include <proto/wb.h>
@@ -119,8 +116,8 @@
#include "amiga/arexx.h"
#include "amiga/bitmap.h"
#include "amiga/clipboard.h"
-#include "amiga/context_menu.h"
#include "amiga/cookies.h"
+#include "amiga/ctxmenu.h"
#include "amiga/datatypes.h"
#include "amiga/download.h"
#include "amiga/drag.h"
@@ -144,6 +141,7 @@
#include "amiga/print.h"
#include "amiga/schedule.h"
#include "amiga/search.h"
+#include "amiga/selectmenu.h"
#include "amiga/theme.h"
#include "amiga/tree.h"
#include "amiga/utf8.h"
@@ -346,13 +344,14 @@ bool ami_locate_resource(char *fullpath, const char *file)
/* Check NetSurf user data area first */
- strcpy(fullpath, current_user_dir);
- found = ami_gui_check_resource(fullpath, file);
- if(found) return true;
+ if(current_user_dir != NULL) {
+ strcpy(fullpath, current_user_dir);
+ found = ami_gui_check_resource(fullpath, file);
+ if(found) return true;
+ }
/* Check current theme directory */
- if(nsoption_charp(theme))
- {
+ if(nsoption_charp(theme)) {
strcpy(fullpath, nsoption_charp(theme));
found = ami_gui_check_resource(fullpath, file);
if(found) return true;
@@ -362,28 +361,23 @@ bool ami_locate_resource(char *fullpath, const char *file)
locale = OpenLocale(NULL);
- for(i=0;i<10;i++)
- {
+ for(i=0;i<10;i++) {
strcpy(fullpath,"PROGDIR:Resources/");
- if(locale->loc_PrefLanguages[i])
- {
+ if(locale->loc_PrefLanguages[i]) {
ami_gui_map_filename(&remapped, "PROGDIR:Resources",
locale->loc_PrefLanguages[i], "LangNames");
netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
found = ami_gui_check_resource(fullpath, file);
- }
- else
- {
+ } else {
continue;
}
if(found) break;
}
- if(!found)
- {
+ if(!found) {
/* If not found yet, check in PROGDIR:Resources/en,
* might not be in user's preferred languages */
@@ -393,8 +387,7 @@ bool ami_locate_resource(char *fullpath, const char *file)
CloseLocale(locale);
- if(!found)
- {
+ if(!found) {
/* Lastly check directly in PROGDIR:Resources */
strcpy(fullpath, "PROGDIR:Resources/");
@@ -546,9 +539,8 @@ static nserror ami_set_options(struct nsoption_s *defaults)
STRPTR tempacceptlangs;
char temp[1024];
- /* The following line disables the popupmenu.class select menu
- ** This will become a user option when/if popupmenu.class is
- ** updated to show more items than can fit in one column vertically
+ /* The following line disables the popupmenu.class select menu.
+ ** It's not recommended to use it!
*/
nsoption_set_bool(core_select_menu, true);
@@ -631,9 +623,6 @@ static nserror ami_set_options(struct nsoption_s *defaults)
}
}
- if(popupmenu_lib_ok == FALSE)
- nsoption_set_bool(context_menu, false);
-
#ifndef __amigaos4__
nsoption_set_bool(download_notify, false);
nsoption_set_bool(font_antialiasing, false);
@@ -1107,6 +1096,10 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB],
gwin->win, NULL, GA_Disabled, tabclose, TAG_DONE);
}
+
+ /* Update the back/forward buttons history context menu */
+ ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK, gwin);
+ ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD, gwin);
}
void ami_gui_history(struct gui_window_2 *gwin, bool back)
@@ -1322,7 +1315,7 @@ static bool ami_spacebox_to_ns_coords(struct gui_window_2 *gwin, int
*x, int *y,
return true;
}
-static bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
+bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
int mouse_x, int mouse_y)
{
int ns_x, ns_y;
@@ -1694,7 +1687,7 @@ static void gui_window_set_icon(struct gui_window *g, hlcache_handle
*icon)
} else {
tag = BLITA_MaskPlane;
tag_data = (ULONG)ami_bitmap_get_mask(icon_bitmap, 16, 16, bm);
- minterm = (ABC|ABNC|ANBC);
+ minterm = MINTERM_SRCMASK;
}
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_ICON], &bbox) !=
NSERROR_OK) {
@@ -1923,7 +1916,6 @@ static void ami_handle_msg(void)
if((x>=xs) && (y>=ys) && (x<width+xs) &&
(y<height+ys))
{
ami_update_quals(gwin);
- ami_context_menu_mouse_trap(gwin, TRUE);
if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
{
@@ -1939,11 +1931,7 @@ static void ami_handle_msg(void)
{
browser_window_mouse_track(gwin->gw->bw,gwin->mouse_state |
gwin->key_state,x,y);
}
- }
- else
- {
- ami_context_menu_mouse_trap(gwin, FALSE);
-
+ } else {
if(!gwin->mouse_state) ami_set_pointer(gwin, GUI_POINTER_DEFAULT, true);
}
break;
@@ -1993,10 +1981,6 @@ static void ami_handle_msg(void)
switch(code)
{
- case MENUDOWN:
- ami_context_menu_show(gwin,x,y);
- break;
-
case SELECTUP:
if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
{
@@ -2270,104 +2254,10 @@ static void ami_handle_msg(void)
if((ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) &&
((31 < nskey) && (nskey < 127))) {
- /* We are duplicating the menu shortcuts here, as if RMBTRAP is
- * active (ie. when context menus are enabled and the mouse is over
- * the browser rendering area), Intuition also does not catch the
- * menu shortcut key presses. Context menus possibly need to be
- * changed to use MENUVERIFY not RMBTRAP.
- * NB: Some keypresses are converted to generic keypresses above
- * rather than being "menu-emulated" here.
- */
+ /* NB: Some keypresses are converted to generic keypresses above
+ * rather than being "menu-emulated" here. */
switch(nskey)
{
- case 'n':
- if ((nsoption_bool(kiosk_mode) == false)) {
- nsurl *urlns;
- nserror error;
-
- error = nsurl_create(nsoption_charp(homepage_url), &urlns);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
- urlns,
- NULL,
- gwin->gw->bw,
- NULL);
- nsurl_unref(urlns);
- }
- if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
- }
-
- }
- break;
-
- case 't':
- if((nsoption_bool(kiosk_mode) == false)) {
- nsurl *urlns;
- nserror error;
-
- error = nsurl_create(nsoption_charp(homepage_url), &urlns);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY |
- BW_CREATE_TAB,
- urlns,
- NULL,
- gwin->gw->bw,
- NULL);
- nsurl_unref(urlns);
- }
- if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
- }
-
- }
- break;
-
- case 'k':
- if((nsoption_bool(kiosk_mode) == false))
- browser_window_destroy(gwin->gw->bw);
- break;
-
- case 'o':
- ami_file_open(gwin);
- break;
-
- case 's':
- ami_file_save_req(AMINS_SAVE_SOURCE, gwin,
- browser_window_get_content(gwin->gw->bw));
- break;
-
- case 'p':
- ami_print_ui(browser_window_get_content(gwin->gw->bw));
- break;
-
- case 'q':
- if((nsoption_bool(kiosk_mode) == false))
- ami_quit_netsurf();
- break;
-
- case 'f':
- ami_search_open(gwin->gw);
- break;
-
- case 'h':
- if((nsoption_bool(kiosk_mode) == false))
- ami_tree_open(hotlist_window, AMI_TREE_HOTLIST);
- break;
-
- case '-':
- if(gwin->gw->scale > 0.1)
- ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1);
- break;
-
- case '=':
- ami_gui_set_scale(gwin->gw, 1.0);
- break;
-
- case '+':
- ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1);
- break;
-
/* The following aren't available from the menu at the moment */
case 'r': // reload
@@ -3042,7 +2932,7 @@ static void gui_quit(void)
if(nsscreentitle) FreeVec(nsscreentitle);
LOG("Freeing menu items");
- ami_context_menu_free();
+ ami_ctxmenu_free();
ami_menu_free_glyphs();
LOG("Freeing mouse pointers");
@@ -3319,6 +3209,7 @@ static void ami_toggletabbar(struct gui_window_2 *gwin, bool show)
GA_ID, GID_TABS,
GA_RelVerify, TRUE,
GA_Underscore, 13, // disable kb shortcuts
+ GA_ContextMenu, ami_ctxmenu_clicktab_create(gwin),
CLICKTAB_Labels, &gwin->tab_list,
CLICKTAB_LabelTruncate, TRUE,
CLICKTAB_CloseImage, gwin->objects[GID_CLOSETAB_BM],
@@ -3854,7 +3745,7 @@ gui_window_create(struct browser_window *bw,
}
ami_NewMinList(&g->shared->shared_pens);
-
+
g->shared->scrollerhook.h_Entry = (void *)ami_scroller_hook;
g->shared->scrollerhook.h_Data = g->shared;
@@ -3866,6 +3757,11 @@ gui_window_create(struct browser_window *bw,
newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook;
newprefs_hook.h_Data = 0;
+
+ g->shared->ctxmenu_hook = ami_ctxmenu_get_hook(g->shared);
+ g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK] = NULL;
+ g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD] = NULL;
+ g->shared->clicktab_ctxmenu = NULL;
if(nsoption_bool(window_simple_refresh) == true) {
refresh_mode = WA_SimpleRefresh;
@@ -3885,10 +3781,9 @@ gui_window_create(struct browser_window *bw,
(locked_screen == TRUE) &&
(strcmp(nsoption_charp(pubscreen_name), "Workbench") == 0))
iconifygadget = TRUE;
- ami_create_menu(g->shared);
-#ifndef __amigaos4__
- struct Menu *menu = ami_menu_create_os3(g->shared, g->shared->menu);
-#endif
+
+ struct Menu *menu = ami_menu_create(g->shared);
+
NewList(&g->shared->tab_list);
g->tab_node = AllocClickTabNode(TNA_Text,messages_get("NetSurf"),
TNA_Number, 0,
@@ -4029,6 +3924,7 @@ gui_window_create(struct browser_window *bw,
WA_ReportMouse,TRUE,
refresh_mode, TRUE,
WA_SizeBBottom, TRUE,
+ WA_ContextMenuHook, g->shared->ctxmenu_hook,
WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE |
IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
IDCMP_RAWKEY | idcmp_sizeverify |
@@ -4036,11 +3932,7 @@ gui_window_create(struct browser_window *bw,
IDCMP_REFRESHWINDOW |
IDCMP_ACTIVEWINDOW | IDCMP_EXTENDEDMOUSE,
WINDOW_IconifyGadget, iconifygadget,
-#ifdef __amigaos4__
- WINDOW_NewMenu, g->shared->menu,
-#else
WINDOW_MenuStrip, menu,
-#endif
WINDOW_MenuUserData, WGUD_HOOK,
WINDOW_NewPrefsHook, &newprefs_hook,
WINDOW_IDCMPHook, &g->shared->scrollerhook,
@@ -4056,9 +3948,10 @@ gui_window_create(struct browser_window *bw,
LAYOUT_AddChild, g->shared->objects[GID_TOOLBARLAYOUT] = LayoutHObj,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_AddChild, g->shared->objects[GID_BACK] = ButtonObj,
- GA_ID,GID_BACK,
- GA_RelVerify,TRUE,
- GA_Disabled,TRUE,
+ GA_ID, GID_BACK,
+ GA_RelVerify, TRUE,
+ GA_Disabled, TRUE,
+ GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK,
g->shared),
GA_HintInfo, g->shared->helphints[GID_BACK],
BUTTON_RenderImage,BitMapObj,
BITMAP_SourceFile,nav_west,
@@ -4071,9 +3964,10 @@ gui_window_create(struct browser_window *bw,
CHILD_WeightedWidth,0,
CHILD_WeightedHeight,0,
LAYOUT_AddChild, g->shared->objects[GID_FORWARD] = ButtonObj,
- GA_ID,GID_FORWARD,
- GA_RelVerify,TRUE,
- GA_Disabled,TRUE,
+ GA_ID, GID_FORWARD,
+ GA_RelVerify, TRUE,
+ GA_Disabled, TRUE,
+ GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD,
g->shared),
GA_HintInfo, g->shared->helphints[GID_FORWARD],
BUTTON_RenderImage,BitMapObj,
BITMAP_SourceFile,nav_east,
@@ -4306,11 +4200,15 @@ gui_window_create(struct browser_window *bw,
"frbuttonclass", /**\todo find appropriate class which works on OS3 */
GA_ID, GID_STATUS,
GA_Left, scrn->WBorLeft + 2,
+#ifdef __amigaos4__
GA_RelBottom, -((2 + height + scrn->WBorBottom - scrn->RastPort.TxHeight)/2),
+ GA_BottomBorder, TRUE,
+#else
+ GA_Top, g->shared->win->Height,
+#endif
GA_Width, width,
GA_Height, 1 + height - scrn->WBorBottom,
GA_DrawInfo, dri,
- GA_BottomBorder, TRUE,
GA_ReadOnly, TRUE,
GA_Disabled, TRUE,
GA_Image, (struct Image *)NewObject(
@@ -4428,8 +4326,7 @@ static void gui_window_destroy(struct gui_window *g)
cur_gw = NULL;
- if(g->shared->tabs > 1)
- {
+ if(g->shared->tabs > 1) {
SetGadgetAttrs((struct Gadget
*)g->shared->objects[GID_TABS],g->shared->win,NULL,
CLICKTAB_Labels,~0,
TAG_DONE);
@@ -4472,7 +4369,6 @@ static void gui_window_destroy(struct gui_window *g)
DisposeObject(g->shared->objects[OID_MAIN]);
ami_gui_appicon_remove(g->shared);
if(g->shared->appwin) RemoveAppWindow(g->shared->appwin);
-
ami_gui_hotlist_toolbar_free(g->shared, &g->shared->hotlist_toolbar_list);
/* These aren't freed by the above.
@@ -4486,10 +4382,14 @@ static void gui_window_destroy(struct gui_window *g)
ami_gui_opts_websearch_free(g->shared->web_search_list);
if(g->shared->search_bm) DisposeObject(g->shared->search_bm);
+ /* This appears to be disposed along with the ClickTab object
+ if(g->shared->clicktab_ctxmenu) DisposeObject((Object
*)g->shared->clicktab_ctxmenu); */
+ DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK]);
+ DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD]);
+ ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
ami_free_menulabs(g->shared);
-#ifndef __amigaos4__
- ami_menu_free_os3(g->shared);
-#endif
+ ami_menu_free(g->shared);
+
free(g->shared->wintitle);
ami_utf8_free(g->shared->status);
FreeVec(g->shared->svbuffer);
@@ -4498,8 +4398,7 @@ static void gui_window_destroy(struct gui_window *g)
free(g->shared->helphints[gid]);
DelObject(g->shared->node);
- if(g->tab_node)
- {
+ if(g->tab_node) {
Remove(g->tab_node);
FreeClickTabNode(g->tab_node);
}
@@ -4993,12 +4892,28 @@ static void gui_window_set_status(struct gui_window *g, const char
*text)
static nserror gui_window_set_url(struct gui_window *g, nsurl *url)
{
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
+ char *url_lc = NULL;
+
if(!g) return NSERROR_OK;
- if (g == g->shared->gw) {
+ if(g == g->shared->gw) {
+ if(nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) {
+ url_lc = ami_utf8_easy(idn_url_s);
+ }
+ }
+
RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL],
- g->shared->win, NULL, STRINGA_TextVal,
- nsurl_access(url), TAG_DONE);
+ g->shared->win, NULL,
+ STRINGA_TextVal, url_lc ? url_lc : nsurl_access(url),
+ TAG_DONE);
+
+ if(url_lc) {
+ ami_utf8_free(url_lc);
+ if(idn_url_s) free(idn_url_s);
+ }
}
ami_update_buttons(g->shared);
@@ -5049,8 +4964,8 @@ static nserror gui_search_web_provider_update(const char
*provider_name,
ULONG bm_masking_tag = TAG_IGNORE;
- if(GfxBase->LibNode.lib_Version >= 54) { /* chooser 53.21, but check gfx.lib
- * is FE as it's easier */
+ if(LIB_IS_AT_LEAST((struct Library *)ChooserBase, 53, 21)) {
+ /* Broken in earlier versions */
bm_masking_tag = BITMAP_Masking;
}
@@ -5451,19 +5366,6 @@ int main(int argc, char** argv)
/* Open splash window */
Object *splash_window = ami_gui_splash_open();
- /* Open popupmenu.library just to check the version.
- * Versions older than 53.11 are dangerous, so we
- * forcibly disable context menus if these are in use.
- */
- popupmenu_lib_ok = FALSE;
-#ifdef __amigaos4__
- if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) {
- LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version,
PopupMenuBase->lib_Revision);
- if(LIB_IS_AT_LEAST((struct Library *)PopupMenuBase, 53, 11))
- popupmenu_lib_ok = TRUE;
- CloseLibrary(PopupMenuBase);
- }
-#endif
if (ami_open_resources() == false) { /* alloc message ports */
ami_misc_fatal_error("Unable to allocate resources");
return RETURN_FAIL;
@@ -5528,7 +5430,6 @@ int main(int argc, char** argv)
ami_openurl_open();
ami_amiupdate(); /* set env-vars for AmiUpdate */
ami_init_fonts();
- ami_context_menu_init();
save_complete_init();
ami_theme_init();
ami_init_mouse_pointers();
@@ -5544,6 +5445,8 @@ int main(int argc, char** argv)
gui_init2(argc, argv);
+ ami_ctxmenu_init(); /* Requires screen pointer */
+
ami_gui_splash_close(splash_window);
strlcpy(script, nsoption_charp(arexx_dir), 1024);
diff --git a/amiga/gui.h b/amiga/gui.h
old mode 100755
new mode 100644
index adad63d..6a01082
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2014 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2015 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf,
http://www.netsurf-browser.org/
*
@@ -18,15 +18,16 @@
#ifndef AMIGA_GUI_H
#define AMIGA_GUI_H
-
+#include <stdbool.h>
#include <graphics/rastport.h>
-#include "amiga/object.h"
#include <intuition/classusr.h>
#include <dos/dos.h>
#include <devices/inputevent.h>
+#include "amiga/menu.h"
+#include "amiga/object.h"
#include "amiga/os3support.h"
#include "amiga/plotters.h"
-#include "amiga/menu.h"
+#include "desktop/gui_window.h"
#ifdef __amigaos4__
#define HOOKF(ret,func,type,ptr,msgtype) static ret func(struct Hook *hook, type ptr,
msgtype msg)
@@ -131,15 +132,16 @@ struct gui_window_2 {
struct DiskObject *dobj; /* iconify appicon */
struct Hook favicon_hook;
struct Hook throbber_hook;
+ struct Hook *ctxmenu_hook;
+ Object *history_ctxmenu[2];
+ Object *clicktab_ctxmenu;
gui_drag_type drag_op;
struct IBox *ptr_lock;
struct AppWindow *appwin;
struct MinList shared_pens;
gui_pointer_shape mouse_pointer;
-#ifndef __amigaos4__
- struct NewMenu *menu_os3;
- struct VisualInfo *vi;
-#endif
+ struct Menu *imenu; /* Intuition menu */
+ struct VisualInfo *vi; /* For GadTools menu */
};
struct gui_window
@@ -173,6 +175,8 @@ void ami_schedule_redraw(struct gui_window_2 *gwin, bool
full_redraw);
STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
+bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
+ int mouse_x, int mouse_y);
BOOL ami_gadget_hit(Object *obj, int x, int y);
void ami_gui_history(struct gui_window_2 *gwin, bool back);
void ami_gui_hotlist_update_all(void);
@@ -220,6 +224,5 @@ struct MsgPort *sport;
struct gui_window *cur_gw;
struct gui_globals browserglob;
BOOL ami_autoscroll;
-BOOL popupmenu_lib_ok;
#endif
diff --git a/amiga/gui_options.c b/amiga/gui_options.c
index d42aa16..cfa78e8 100755
--- a/amiga/gui_options.c
+++ b/amiga/gui_options.c
@@ -71,6 +71,7 @@
#include "amiga/libs.h"
#include "amiga/misc.h"
#include "amiga/object.h"
+#include "amiga/selectmenu.h"
#include "amiga/theme.h"
#include "amiga/utf8.h"
@@ -132,7 +133,7 @@ enum
GID_OPTS_TAB_CLOSE,
GID_OPTS_SEARCH_PROV,
GID_OPTS_CLIPBOARD,
- GID_OPTS_CONTEXTMENU,
+ GID_OPTS_SELECTMENU,
GID_OPTS_STARTUP_NO_WIN,
GID_OPTS_CLOSE_NO_QUIT,
GID_OPTS_DOCKY,
@@ -210,6 +211,9 @@ struct ami_gui_opts_window {
struct nsObject *node;
struct Window *win;
Object *objects[GID_OPTS_LAST];
+#ifndef __amigaos4__
+ struct List clicktablist;
+#endif
};
static struct ami_gui_opts_window *gow = NULL;
@@ -223,7 +227,7 @@ CONST_STRPTR fontopts[6];
CONST_STRPTR gadlab[OPTS_LAST];
struct List *websearch_list;
-static void ami_gui_opts_setup(void)
+static void ami_gui_opts_setup(struct ami_gui_opts_window *gow)
{
tabs[0] = (char *)ami_utf8_easy((char *)messages_get("con_general"));
tabs[1] = (char *)ami_utf8_easy((char *)messages_get("Display"));
@@ -240,6 +244,19 @@ static void ami_gui_opts_setup(void)
tabs[8] = NULL;
#endif
+#ifndef __amigaos4__
+ int i = 0;
+ struct Node *node;
+
+ NewList(&gow->clicktablist);
+
+ do {
+ node = AllocClickTabNode(TNA_Text, tabs[i], TNA_Number, i, TAG_DONE);
+ AddTail(&gow->clicktablist, node);
+ i++;
+ } while (tabs[i] != 0);
+#endif
+
screenopts[0] = (char *)ami_utf8_easy((char *)messages_get("ScreenOwn"));
screenopts[1] = (char *)ami_utf8_easy((char *)messages_get("ScreenWB"));
screenopts[2] = (char *)ami_utf8_easy((char *)messages_get("ScreenPublic"));
@@ -312,7 +329,7 @@ static void ami_gui_opts_setup(void)
gadlab[GID_OPTS_TAB_CLOSE] = (char *)ami_utf8_easy((char
*)messages_get("TabClose"));
gadlab[GID_OPTS_SEARCH_PROV] = (char *)ami_utf8_easy((char
*)messages_get("SearchProvider"));
gadlab[GID_OPTS_CLIPBOARD] = (char *)ami_utf8_easy((char
*)messages_get("ClipboardUTF8"));
- gadlab[GID_OPTS_CONTEXTMENU] = (char *)ami_utf8_easy((char
*)messages_get("ContextMenu"));
+ gadlab[GID_OPTS_SELECTMENU] = (char *)ami_utf8_easy((char
*)messages_get("PopupMenu"));
gadlab[GID_OPTS_STARTUP_NO_WIN] = (char *)ami_utf8_easy((char
*)messages_get("OptionNoWindow"));
gadlab[GID_OPTS_CLOSE_NO_QUIT] = (char *)ami_utf8_easy((char
*)messages_get("OptionNoQuit"));
gadlab[GID_OPTS_DOCKY] = (char *)ami_utf8_easy((char
*)messages_get("OptionDocky"));
@@ -377,7 +394,7 @@ static void ami_gui_opts_setup(void)
fontopts[5] = NULL;
}
-static void ami_gui_opts_free(void)
+static void ami_gui_opts_free(struct ami_gui_opts_window *gow)
{
int i;
@@ -397,6 +414,19 @@ static void ami_gui_opts_free(void)
if(nativebmopts[i]) free((APTR)nativebmopts[i]);
ami_gui_opts_websearch_free(websearch_list);
+
+#ifndef __amigaos4__
+ struct Node *node;
+ struct Node *nnode;
+
+ if(IsListEmpty((struct List *)&gow->clicktablist)) return;
+ node = GetHead((struct List *)&gow->clicktablist);
+
+ do {
+ nnode = GetSucc(node);
+ if(node) FreeClickTabNode(node);
+ } while((node = nnode));
+#endif
}
void ami_gui_opts_open(void)
@@ -527,9 +557,10 @@ void ami_gui_opts_open(void)
if(!gow)
{
- ami_gui_opts_setup();
-
gow = ami_misc_allocvec_clear(sizeof(struct ami_gui_opts_window), 0);
+ if(gow == NULL) return;
+
+ ami_gui_opts_setup(gow);
gow->objects[OID_MAIN] = WindowObj,
WA_ScreenTitle, ami_gui_get_screen_title(),
@@ -548,7 +579,11 @@ void ami_gui_opts_open(void)
WINDOW_ParentGroup, gow->objects[GID_OPTS_MAIN] = LayoutVObj,
LAYOUT_AddChild, ClickTabObj,
GA_RelVerify, TRUE,
+#ifdef __amigaos4__
GA_Text, tabs,
+#else
+ CLICKTAB_Labels, &gow->clicktablist,
+#endif
CLICKTAB_PageGroup, PageObj,
/*
** General
@@ -1326,22 +1361,22 @@ void ami_gui_opts_open(void)
LAYOUT_BevelStyle, BVS_GROUP,
LAYOUT_Label, gadlab[GRP_OPTS_MISC],
LAYOUT_SpaceOuter, TRUE,
-#ifdef __amigaos4__
- LAYOUT_AddChild, gow->objects[GID_OPTS_CONTEXTMENU] =
CheckBoxObj,
- GA_ID, GID_OPTS_CONTEXTMENU,
- GA_RelVerify, TRUE,
- GA_Text, gadlab[GID_OPTS_CONTEXTMENU],
- GA_Selected, nsoption_bool(context_menu),
- GA_Disabled, !popupmenu_lib_ok,
- CheckBoxEnd,
-#endif
LAYOUT_AddChild, gow->objects[GID_OPTS_FASTSCROLL] =
CheckBoxObj,
GA_ID, GID_OPTS_FASTSCROLL,
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_FASTSCROLL],
GA_Selected, nsoption_bool(faster_scroll),
CheckBoxEnd,
- LayoutEnd, // context menus
+#ifdef __amigaos4__
+ LAYOUT_AddChild, gow->objects[GID_OPTS_SELECTMENU] =
CheckBoxObj,
+ GA_ID, GID_OPTS_SELECTMENU,
+ GA_RelVerify, TRUE,
+ GA_Text, gadlab[GID_OPTS_SELECTMENU],
+ GA_Selected, !nsoption_bool(core_select_menu),
+ GA_Disabled, !ami_selectmenu_is_safe(),
+ CheckBoxEnd,
+#endif
+ LayoutEnd, // misc
CHILD_WeightedHeight, 0,
LayoutEnd, // page vgroup
@@ -1821,11 +1856,11 @@ static void ami_gui_opts_use(bool save)
nsoption_set_bool(clipboard_write_utf8, false);
}
- GetAttr(GA_Selected,gow->objects[GID_OPTS_CONTEXTMENU],(ULONG *)&data);
+ GetAttr(GA_Selected,gow->objects[GID_OPTS_SELECTMENU],(ULONG *)&data);
if (data) {
- nsoption_set_bool(context_menu, true);
+ nsoption_set_bool(core_select_menu, false);
} else {
- nsoption_set_bool(context_menu, false);
+ nsoption_set_bool(core_select_menu, true);
}
GetAttr(GA_Selected,gow->objects[GID_OPTS_STARTUP_NO_WIN],(ULONG *)&data);
@@ -1914,9 +1949,9 @@ static void ami_gui_opts_use(bool save)
void ami_gui_opts_close(void)
{
DisposeObject(gow->objects[OID_MAIN]);
+ ami_gui_opts_free(gow);
DelObject(gow->node);
gow = NULL;
- ami_gui_opts_free();
}
BOOL ami_gui_opts_event(void)
diff --git a/amiga/libs.c b/amiga/libs.c
index c20147a..76ac876 100644
--- a/amiga/libs.c
+++ b/amiga/libs.c
@@ -27,6 +27,8 @@
#include <proto/intuition.h>
#include <proto/utility.h>
+#include <graphics/gfxbase.h> /* Needed for v54 version check */
+
#ifndef __amigaos4__
/* OS3 needs these for the XXXX_GetClass() functions */
#include <proto/arexx.h>
@@ -75,8 +77,8 @@
if(PREFIX##Base) CloseLibrary((struct Library *)PREFIX##Base);
#define AMINS_LIB_STRUCT(PREFIX) \
- struct PREFIX##Base *PREFIX##Base; \
- struct PREFIX##IFace *I##PREFIX;
+ struct PREFIX##Base *PREFIX##Base = NULL; \
+ struct PREFIX##IFace *I##PREFIX = NULL;
#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
LOG("Opening %s v%d", CLASS, CLASSVER); \
@@ -123,7 +125,7 @@
if(PREFIX##Base) CloseLibrary((struct Library *)PREFIX##Base);
#define AMINS_LIB_STRUCT(PREFIX) \
- struct PREFIX##Base *PREFIX##Base;
+ struct PREFIX##Base *PREFIX##Base = NULL;
#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
LOG("Opening %s v%d", CLASS, CLASSVER); \
@@ -213,10 +215,11 @@ bool ami_libs_open(void)
AMINS_LIB_OPEN("locale.library", 38, Locale, "main",
1, true)
AMINS_LIB_OPEN("workbench.library", 37, Workbench, "main",
1, true)
- /*\todo This is down here as we need to check the graphics.library version
- * before opening. If it is sufficiently new enough we can avoid using P96
+ /* This is down here as we need to check the graphics.library version
+ * before opening. If it is sufficiently new enough we can avoid using P96.
*/
- AMINS_LIB_OPEN("Picasso96API.library", 0, P96, "main",
1, false)
+ if(GfxBase->LibNode.lib_Version < 54)
+ AMINS_LIB_OPEN("Picasso96API.library", 0, P96, "main",
1, false)
/* NB: timer.device is opened in schedule.c (ultimately by the scheduler process).
* The library base and interface are obtained there, rather than here, due to
@@ -235,7 +238,6 @@ bool ami_libs_open(void)
* NB: the last argument should be "true" only if the class also has
* library functions we use.
*/
-
AMINS_CLASS_OPEN("arexx.class", 44, ARexx, AREXX,
false)
AMINS_CLASS_OPEN("images/bevel.image", 44, Bevel, BEVEL,
false)
AMINS_CLASS_OPEN("images/bitmap.image", 44, BitMap, BITMAP,
false)
diff --git a/amiga/menu.c b/amiga/menu.c
index 556b014..25345d0 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -28,6 +28,7 @@
#include <proto/utility.h>
#ifdef __amigaos4__
#include <dos/anchorpath.h>
+#include <dos/obsolete.h> /* Needed for ExAll() */
#endif
#include <libraries/gadtools.h>
@@ -517,19 +518,15 @@ void ami_free_menulabs(struct gui_window_2 *gwin)
{
int i;
- for(i=0;i<=AMI_MENU_AREXX_MAX;i++)
- {
- if(gwin->menulab[i] && (gwin->menulab[i] != NM_BARLABEL))
- {
- if(gwin->menutype[i] & MENU_IMAGE)
- {
- DisposeObject(gwin->menuobj[i]);
+ for(i=0;i<=AMI_MENU_AREXX_MAX;i++) {
+ if(gwin->menulab[i] && (gwin->menulab[i] != NM_BARLABEL)) {
+ if(gwin->menutype[i] & MENU_IMAGE) {
+ if(gwin->menuobj[i]) DisposeObject(gwin->menuobj[i]);
}
ami_utf8_free(gwin->menulab[i]);
- if(i >= AMI_MENU_AREXX)
- {
+ if(i >= AMI_MENU_AREXX) {
if(gwin->menu_hook[i].h_Data) free(gwin->menu_hook[i].h_Data);
}
}
@@ -564,20 +561,24 @@ static void ami_menu_alloc_item(struct gui_window_2 *gwin, int num,
UBYTE type,
gwin->menulab[num] = ami_utf8_easy(messages_get(label));
}
}
-
+
gwin->menuicon[num] = NULL;
if(key) gwin->menukey[num] = key;
if(func) gwin->menu_hook[num].h_Entry = (HOOKFUNC)func;
if(hookdata) gwin->menu_hook[num].h_Data = hookdata;
- if(icon) {
- if(ami_locate_resource(menu_icon, icon) == true) {
- gwin->menuicon[num] = (char *)strdup(menu_icon);
- } else {
- /* If the requested icon can't be found, put blank space in instead */
- gwin->menuicon[num] = (char *)strdup(NSA_SPACE);
+#ifdef __amigaos4__
+ if(LIB_IS_AT_LEAST((struct Library *)GadToolsBase, 53, 7)) {
+ if(icon) {
+ if(ami_locate_resource(menu_icon, icon) == true) {
+ gwin->menuicon[num] = (char *)strdup(menu_icon);
+ } else {
+ /* If the requested icon can't be found, put blank space in instead */
+ gwin->menuicon[num] = (char *)strdup(NSA_SPACE);
+ }
}
}
+#endif
}
static void ami_init_menulabs(struct gui_window_2 *gwin)
@@ -703,67 +704,61 @@ static void ami_init_menulabs(struct gui_window_2 *gwin)
/* Menu refresh for hotlist */
void ami_menu_refresh(struct gui_window_2 *gwin)
{
+ struct Menu *menu;
+
SetAttrs(gwin->objects[OID_MAIN],
-#ifdef __amigaos4__
- WINDOW_NewMenu, NULL,
-#else
WINDOW_MenuStrip, NULL,
-#endif
TAG_DONE);
-#ifndef __amigaos4__
- ami_menu_free_os3(gwin->menu_os3);
-#endif
+ ami_menu_free(gwin);
ami_free_menulabs(gwin);
- ami_create_menu(gwin);
-#ifndef __amigaos4__
- gwin->menu_os3 = ami_menu_create_os3(gwin, gwin->menu);
-#endif
+
+ menu = ami_menu_create(gwin);
SetAttrs(gwin->objects[OID_MAIN],
-#ifdef __amigaos4__
- WINDOW_NewMenu, gwin->menu,
-#else
- WINDOW_MenuStrip, gwin->menu_os3,
-#endif
+ WINDOW_MenuStrip, menu,
TAG_DONE);
}
static void ami_menu_load_glyphs(struct DrawInfo *dri)
{
#ifdef __amigaos4__
- for(int i = 0; i < NSA_GLYPH_MAX; i++)
- menu_glyph[i] = NULL;
-
- menu_glyph[NSA_GLYPH_SUBMENU] = NewObject(NULL, "sysiclass",
- SYSIA_Which, MENUSUB,
- SYSIA_DrawInfo, dri,
- TAG_DONE);
- menu_glyph[NSA_GLYPH_AMIGAKEY] = NewObject(NULL, "sysiclass",
- SYSIA_Which, AMIGAKEY,
- SYSIA_DrawInfo, dri,
- TAG_DONE);
- GetAttr(IA_Width, menu_glyph[NSA_GLYPH_SUBMENU],
- (ULONG *)&menu_glyph_width[NSA_GLYPH_SUBMENU]);
- GetAttr(IA_Width, menu_glyph[NSA_GLYPH_AMIGAKEY],
- (ULONG *)&menu_glyph_width[NSA_GLYPH_AMIGAKEY]);
+ if(LIB_IS_AT_LEAST((struct Library *)GadToolsBase, 53, 7)) {
+ for(int i = 0; i < NSA_GLYPH_MAX; i++)
+ menu_glyph[i] = NULL;
+
+ menu_glyph[NSA_GLYPH_SUBMENU] = NewObject(NULL, "sysiclass",
+ SYSIA_Which, MENUSUB,
+ SYSIA_DrawInfo, dri,
+ TAG_DONE);
+ menu_glyph[NSA_GLYPH_AMIGAKEY] = NewObject(NULL, "sysiclass",
+ SYSIA_Which, AMIGAKEY,
+ SYSIA_DrawInfo, dri,
+ TAG_DONE);
+ GetAttr(IA_Width, menu_glyph[NSA_GLYPH_SUBMENU],
+ (ULONG *)&menu_glyph_width[NSA_GLYPH_SUBMENU]);
+ GetAttr(IA_Width, menu_glyph[NSA_GLYPH_AMIGAKEY],
+ (ULONG *)&menu_glyph_width[NSA_GLYPH_AMIGAKEY]);
- menu_glyphs_loaded = true;
+ menu_glyphs_loaded = true;
+ }
#endif
}
void ami_menu_free_glyphs(void)
{
#ifdef __amigaos4__
- int i;
- if(menu_glyphs_loaded == false) return;
-
- for(i = 0; i < NSA_GLYPH_MAX; i++) {
- if(menu_glyph[i]) DisposeObject(menu_glyph[i]);
- menu_glyph[i] = NULL;
- };
+ if(LIB_IS_AT_LEAST((struct Library *)GadToolsBase, 53, 7)) {
+ int i;
+ if(menu_glyphs_loaded == false) return;
+
+ for(i = 0; i < NSA_GLYPH_MAX; i++) {
+ if(menu_glyph[i]) DisposeObject(menu_glyph[i]);
+ menu_glyph[i] = NULL;
+ };
- menu_glyphs_loaded = false;
+ menu_glyphs_loaded = false;
+ }
#endif
}
@@ -888,7 +883,7 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2
*gwin)
if(gwin->menukey[i]) gwin->menu[i].nm_CommKey = &gwin->menukey[i];
gwin->menu[i].nm_Flags = 0;
if(gwin->menu_hook[i].h_Entry) gwin->menu[i].nm_UserData =
&gwin->menu_hook[i];
-
+
if(gwin->menuicon[i]) {
free(gwin->menuicon[i]);
gwin->menuicon[i] = NULL;
@@ -900,25 +895,13 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2
*gwin)
return gwin;
}
-#ifndef __amigaos4__
-void ami_menu_free_os3(struct gui_window_2 *gwin)
+void ami_menu_free(struct gui_window_2 *gwin)
{
- FreeMenus(gwin->menu_os3);
+ FreeMenus(gwin->imenu);
FreeVisualInfo(gwin->vi);
}
-struct Menu *ami_menu_create_os3(struct gui_window_2 *gwin, struct NewMenu *newmenu)
-{
- gwin->vi = GetVisualInfo(scrn, TAG_DONE);
- gwin->menu_os3 = CreateMenus(newmenu, TAG_DONE);
- LayoutMenus(gwin->menu_os3, gwin->vi,
- GTMN_NewLookMenus, TRUE, TAG_DONE);
-
- return gwin->menu_os3;
-}
-#endif
-
-struct NewMenu *ami_create_menu(struct gui_window_2 *gwin)
+struct Menu *ami_menu_create(struct gui_window_2 *gwin)
{
gwin->menu = ami_misc_allocvec_clear(sizeof(struct NewMenu) * (AMI_MENU_AREXX_MAX +
1), 0);
ami_init_menulabs(gwin);
@@ -939,11 +922,19 @@ struct NewMenu *ami_create_menu(struct gui_window_2 *gwin)
if(nsoption_bool(background_images) == true)
gwin->menu[M_IMGBACK].nm_Flags |= CHECKED;
- return(gwin->menu);
+ gwin->vi = GetVisualInfo(scrn, TAG_DONE);
+ gwin->imenu = CreateMenus(gwin->menu, TAG_DONE);
+ LayoutMenus(gwin->imenu, gwin->vi,
+ GTMN_NewLookMenus, TRUE, TAG_DONE);
+
+ /**\todo do we even need to store/keep gwin->menu? **/
+
+ return gwin->imenu;
}
void ami_menu_arexx_scan(struct gui_window_2 *gwin)
{
+ /**\todo Rewrite this to not use ExAll() **/
int item = AMI_MENU_AREXX;
BPTR lock = 0;
UBYTE *buffer;
@@ -1083,8 +1074,8 @@ void ami_menu_update_disabled(struct gui_window *g, hlcache_handle
*c)
#ifdef WITH_PDF_EXPORT
OnMenu(win,AMI_MENU_SAVEAS_PDF);
#endif
- if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY)
- {
+#if 0
+ if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY) {
OnMenu(win,AMI_MENU_COPY);
OnMenu(win,AMI_MENU_CLEAR);
} else {
@@ -1101,7 +1092,12 @@ void ami_menu_update_disabled(struct gui_window *g, hlcache_handle
*c)
OnMenu(win,AMI_MENU_PASTE);
else
OffMenu(win,AMI_MENU_PASTE);
-
+#else
+ OnMenu(win,AMI_MENU_CUT);
+ OnMenu(win,AMI_MENU_COPY);
+ OnMenu(win,AMI_MENU_PASTE);
+ OnMenu(win,AMI_MENU_CLEAR);
+#endif
OnMenu(win,AMI_MENU_SELECTALL);
OnMenu(win,AMI_MENU_FIND);
OffMenu(win,AMI_MENU_SAVEAS_IFF);
diff --git a/amiga/menu.h b/amiga/menu.h
index 516aedf..cff42dd 100755
--- a/amiga/menu.h
+++ b/amiga/menu.h
@@ -137,15 +137,12 @@ struct gui_window_2 *ami_menu_window_close;
bool ami_menu_check_toggled;
void ami_free_menulabs(struct gui_window_2 *gwin);
-struct NewMenu *ami_create_menu(struct gui_window_2 *gwin);
+struct Menu *ami_menu_create(struct gui_window_2 *gwin);
void ami_menu_refresh(struct gui_window_2 *gwin);
void ami_menu_update_checked(struct gui_window_2 *gwin);
void ami_menu_update_disabled(struct gui_window *g, hlcache_handle *c);
void ami_menu_free_glyphs(void);
+void ami_menu_free(struct gui_window_2 *gwin);
-#ifndef __amigaos4__
-void ami_menu_free_os3(struct gui_window_2 *gwin);
-struct Menu *ami_menu_create_os3(struct gui_window_2 *gwin, struct NewMenu *newmenu);
#endif
-#endif
diff --git a/amiga/options.h b/amiga/options.h
index a98b1e8..317e5df 100644
--- a/amiga/options.h
+++ b/amiga/options.h
@@ -34,7 +34,6 @@ NSOPTION_INTEGER(screen_ydpi, 85)
NSOPTION_INTEGER(cache_bitmaps, 0)
NSOPTION_STRING(theme, "PROGDIR:Resources/Themes/Default")
NSOPTION_BOOL(clipboard_write_utf8, false)
-NSOPTION_BOOL(context_menu, true)
NSOPTION_BOOL(truecolour_mouse_pointers, false)
NSOPTION_BOOL(os_mouse_pointers, true)
NSOPTION_BOOL(use_openurl_lib, false)
@@ -88,4 +87,8 @@ NSOPTION_INTEGER(redraw_tile_size_y, 0)
NSOPTION_INTEGER(monitor_aspect_x, 0)
NSOPTION_INTEGER(monitor_aspect_y, 0)
NSOPTION_BOOL(accept_lang_locale, true)
+/* Options relevant for OS3 only */
+#ifndef __amigaos4__
+NSOPTION_BOOL(friend_bitmap, false)
+#endif
diff --git a/amiga/os3support.c b/amiga/os3support.c
index cea466c..7235d8c 100644
--- a/amiga/os3support.c
+++ b/amiga/os3support.c
@@ -33,6 +33,7 @@
#include <proto/dos.h>
#include <proto/utility.h>
+#include <diskfont/diskfont.h>
#include <diskfont/diskfonttag.h>
#include <intuition/gadgetclass.h>
@@ -49,25 +50,47 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List
*list, ULONG fl
int64 size = 0;
struct TagItem *ti;
UBYTE *buffer;
- STRPTR fname, otagpath;
+ STRPTR fname, otagpath, fontpath;
struct BulletBase *BulletBase;
struct OutlineFont *of = NULL;
struct GlyphEngine *gengine;
char *p = 0;
+ struct FontContentsHeader fch;
if(p = strrchr(fileName, '.'))
*p = '\0';
+ fontpath = (STRPTR)ASPrintf("FONTS:%s.font", fileName);
+ fh = Open(fontpath, MODE_OLDFILE);
+
+ if(fh == 0) {
+ LOG("Unable to open FONT %s", fontpath);
+ FreeVec(fontpath);
+ return NULL;
+ }
+
+ if(Read(fh, &fch, sizeof(struct FontContentsHeader)) != sizeof(struct
FontContentsHeader)) {
+ LOG("Unable to read FONT %s", fontpath);
+ FreeVec(fontpath);
+ Close(fh);
+ return NULL;
+ }
+
+ Close(fh);
+
+ if(fch.fch_FileID != OFCH_ID) {
+ LOG("%s is not an outline font!", fontpath);
+ FreeVec(fontpath);
+ return NULL;
+ }
+
otagpath = (STRPTR)ASPrintf("FONTS:%s.otag", fileName);
fh = Open(otagpath, MODE_OLDFILE);
if(p) *p = '.';
if(fh == 0) {
- /*\todo we should be opening the .font file too and checking
- * for the magic bytes to indicate this is an outline font.
- */
- LOG("Unable to open %s", otagpath);
+ LOG("Unable to open OTAG %s", otagpath);
FreeVec(otagpath);
return NULL;
}
@@ -114,7 +137,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List
*list, ULONG fl
BulletBase = OpenLibrary(fname, 0L);
if(BulletBase == NULL) {
- LOG("Unable to open %s", fname);
+ LOG("Unable to open font engine %s", fname);
FreeVec(buffer);
FreeVec(fname);
FreeVec(otagpath);
diff --git a/amiga/os3support.h b/amiga/os3support.h
index 128e6bf..45a917a 100644
--- a/amiga/os3support.h
+++ b/amiga/os3support.h
@@ -73,6 +73,7 @@
#define GETFONT_ScalableOnly TAG_IGNORE
#define PDTA_PromoteMask TAG_IGNORE
#define RPTAG_APenColor TAG_IGNORE
+#define GA_ContextMenu TAG_IGNORE
#define GA_HintInfo TAG_IGNORE
#define GAUGEIA_Level TAG_IGNORE
#define IA_InBorder TAG_IGNORE
@@ -81,6 +82,7 @@
#define SBNA_Text TAG_IGNORE
#define TNA_CloseGadget TAG_IGNORE
#define TNA_HintInfo TAG_IGNORE
+#define WA_ContextMenuHook TAG_IGNORE
#define WA_ToolBox TAG_IGNORE
#define WINDOW_BuiltInScroll TAG_IGNORE
#define WINDOW_NewMenu TAG_IGNORE
@@ -119,6 +121,9 @@
#define GetFontEnd End
#define GetScreenModeEnd End
+/* MinTerm stuff */
+#define MINTERM_SRCMASK (ABC|ABNC|ANBC)
+
/* Easy compat macros */
/* application */
#define Notify(...) (void)0
diff --git a/amiga/plotters.c b/amiga/plotters.c
index 202d1b8..0af5dd5 100644
--- a/amiga/plotters.c
+++ b/amiga/plotters.c
@@ -120,11 +120,27 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG
height)
gg->layerinfo = NewLayerInfo();
gg->areabuf = AllocVecTagList(AREA_SIZE, NULL);
+
+#ifdef __amigaos4__
gg->tmprasbuf = AllocVecTagList(width * height, NULL);
+#else
+ /* OS3/AGA requires this to be in chip mem. RTG would probably rather it wasn't.
*/
+ gg->tmprasbuf = AllocVec(width * height, MEMF_CHIP);
+#endif
+ /* Friend BitMaps are weird.
+ * For OS4, we shouldn't use a friend BitMap here (see below).
+ * For OS3 AGA, we get no display blitted if we use a friend BitMap,
+ * however on RTG it seems to be a benefit.
+ */
#ifndef __amigaos4__
- /* If you're wondering why this is #ifdeffed, see the note about OS4 friend bitmaps
below */
- friend = scrn->RastPort.BitMap;
+ if(nsoption_bool(friend_bitmap) == true) {
+ friend = scrn->RastPort.BitMap;
+ } else {
+ /* Force friend BitMaps on for obvious RTG screens under OS3.
+ * If we get a bit smarter about this we can lose the user option. */
+ if(depth >= 16) friend = scrn->RastPort.BitMap;
+ }
#endif
if(palette_mapped == true) {
@@ -133,7 +149,8 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG
height)
#ifdef __amigaos4__
/* Screen depth is reported as 24 even when it's actually 32-bit.
* We get freezes and other problems on OS4 if we befriend at any
- * other depths, hence this check. */
+ * other depths, hence this check.
+ */
if(depth >= 24) friend = scrn->RastPort.BitMap;
#endif
gg->bm = ami_rtg_allocbitmap(width, height, 32, 0, friend, RGBFB_A8R8G8B8);
@@ -155,12 +172,11 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG
height)
InstallLayerHook(gg->rp->Layer,LAYERS_NOBACKFILL);
gg->rp->AreaInfo = AllocVecTagList(sizeof(struct AreaInfo), NULL);
-
if((!gg->areabuf) ||
(!gg->rp->AreaInfo)) warn_user("NoMemory","");
InitArea(gg->rp->AreaInfo,gg->areabuf, AREA_SIZE/5);
- gg->rp->TmpRas = AllocVecTagList(sizeof(struct TmpRas), NULL);
+ gg->rp->TmpRas = AllocVecTagList(sizeof(struct TmpRas), NULL);
if((!gg->tmprasbuf) ||
(!gg->rp->TmpRas)) warn_user("NoMemory","");
InitTmpRas(gg->rp->TmpRas, gg->tmprasbuf, width*height);
@@ -542,7 +558,7 @@ static bool ami_bitmap(int x, int y, int width, int height, struct
bitmap *bitma
} else {
tag = BLITA_MaskPlane;
if((tag_data = (ULONG)ami_bitmap_get_mask(bitmap, width, height, tbm)))
- minterm = (ABC|ABNC|ANBC);
+ minterm = MINTERM_SRCMASK;
}
#ifdef __amigaos4__
BltBitMapTags(BLITA_Width,width,
@@ -743,7 +759,7 @@ static void ami_bitmap_tile_hook(struct Hook *hook,struct RastPort
*rp,struct Ba
} else {
tag = BLITA_MaskPlane;
if((tag_data = (ULONG)bfbm->mask))
- minterm = (ABC|ABNC|ANBC);
+ minterm = MINTERM_SRCMASK;
}
BltBitMapTags(BLITA_Width, bfbm->width,
diff --git a/amiga/rtg.c b/amiga/rtg.c
index 2f4b9e1..5e1cac2 100644
--- a/amiga/rtg.c
+++ b/amiga/rtg.c
@@ -47,19 +47,26 @@ void ami_rtg_freebitmap(struct BitMap *bm)
void ami_rtg_writepixelarray(UBYTE *pixdata, struct BitMap *bm,
ULONG width, ULONG height, ULONG bpr, ULONG format)
{
- struct RenderInfo ri;
struct RastPort trp;
- /* This requires P96 currently */
- if(P96Base == NULL) return;
-
- ri.Memory = pixdata;
- ri.BytesPerRow = bpr;
- ri.RGBFormat = format;
-
InitRastPort(&trp);
trp.BitMap = bm;
- p96WritePixelArray((struct RenderInfo *)&ri, 0, 0, &trp, 0, 0, width, height);
+ /* This requires P96 or gfx.lib v54 currently */
+ if(P96Base == NULL) {
+#ifdef __amigaos4__
+ if(GfxBase->LibNode.lib_Version >= 54) {
+ WritePixelArray(pixdata, 0, 0, bpr, PIXF_R8G8B8A8, &trp, 0, 0, width, height);
+ }
+#endif
+ } else {
+ struct RenderInfo ri;
+
+ ri.Memory = pixdata;
+ ri.BytesPerRow = bpr;
+ ri.RGBFormat = format;
+
+ p96WritePixelArray((struct RenderInfo *)&ri, 0, 0, &trp, 0, 0, width, height);
+ }
}
diff --git a/amiga/selectmenu.c b/amiga/selectmenu.c
new file mode 100644
index 0000000..2593178
--- /dev/null
+++ b/amiga/selectmenu.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2008 - 2011 Chris Young <chris(a)unsatisfactorysoftware.co.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/>.
+ */
+
+#ifdef __amigaos4__
+
+#include <stdbool.h>
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/popupmenu.h>
+#include <proto/utility.h>
+#include <reaction/reaction_macros.h>
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "render/form.h"
+#include "desktop/mouse.h"
+
+#include "amiga/gui.h"
+#include "amiga/selectmenu.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+/* Maximum number of items for a popupmenu.class select menu.
+ * 50 is about the limit for my screen, and popupmenu doesn't scroll.
+ * We may need to calculate a value for this based on screen/font size.
+ *
+ * Additional entries will be added to a "More" menu...
+ */
+#define AMI_SELECTMENU_PAGE_MAX 40
+
+/* ...limited to the number of menus defined here... */
+#define AMI_SELECTMENU_MENU_MAX 10
+
+/* ...and resulting in this total number of entries. */
+#define AMI_SELECTMENU_MAX (AMI_SELECTMENU_PAGE_MAX * AMI_SELECTMENU_MENU_MAX)
+
+
+/** Exported interface documented in selectmenu.h **/
+BOOL ami_selectmenu_is_safe(void)
+{
+ struct Library *PopupMenuBase;
+ BOOL popupmenu_lib_ok = FALSE;
+
+ if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) {
+ LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version,
PopupMenuBase->lib_Revision);
+ if(LIB_IS_AT_LEAST((struct Library *)PopupMenuBase, 53, 11))
+ popupmenu_lib_ok = TRUE;
+ CloseLibrary(PopupMenuBase);
+ }
+
+ return popupmenu_lib_ok;
+}
+
+HOOKF(uint32, ami_popup_hook, Object *, item, APTR)
+{
+ uint32 itemid = 0;
+ struct gui_window *gwin = hook->h_Data;
+
+ if(GetAttr(PMIA_ID, item, &itemid)) {
+ form_select_process_selection(gwin->shared->control, itemid);
+ }
+
+ return itemid;
+}
+
+void gui_create_form_select_menu(struct gui_window *g,
+ struct form_control *control)
+{
+ struct Library *PopupMenuBase = NULL;
+ struct PopupMenuIFace *IPopupMenu = NULL;
+ struct Hook selectmenuhook;
+ Object *selectmenuobj;
+ Object *smenu = NULL;
+ Object *currentmenu;
+ Object *submenu = NULL;
+ char *selectmenu_item[AMI_SELECTMENU_MAX];
+ char *more_label;
+ struct form_option *opt = form_select_get_option(control, 0);
+ int i = 0;
+ int n = 0;
+
+ if(ami_selectmenu_is_safe() == FALSE) return;
+
+ if((PopupMenuBase = OpenLibrary("popupmenu.class", 0))) {
+ IPopupMenu = (struct PopupMenuIFace *)GetInterface(PopupMenuBase, "main", 1,
NULL);
+ }
+
+ if(IPopupMenu == NULL) return;
+
+ ClearMem(selectmenu_item, AMI_SELECTMENU_MAX * 4);
+ more_label = ami_utf8_easy(messages_get("More"));
+
+ selectmenuhook.h_Entry = ami_popup_hook;
+ selectmenuhook.h_SubEntry = NULL;
+ selectmenuhook.h_Data = g;
+
+ g->shared->control = control;
+
+ selectmenuobj = PMMENU(form_control_get_name(control)),
+ PMA_MenuHandler, &selectmenuhook, End;
+
+ currentmenu = selectmenuobj;
+
+ while(opt) {
+ selectmenu_item[i] = ami_utf8_easy(opt->text);
+
+ IDoMethod(currentmenu, PM_INSERT,
+ NewObject(POPUPMENU_GetItemClass(), NULL,
+ PMIA_Title, (ULONG)selectmenu_item[i],
+ PMIA_ID, i,
+ PMIA_CheckIt, TRUE,
+ PMIA_Checked, opt->selected,
+ TAG_DONE),
+ ~0);
+
+ opt = opt->next;
+ i++;
+ n++;
+
+ if(n == AMI_SELECTMENU_PAGE_MAX) {
+ if(submenu != NULL) {
+ /* attach the previous submenu */
+ IDoMethod(smenu, PM_INSERT,
+ NewObject(NULL, "popupmenuitem.class",
+ PMIA_Title, more_label,
+ PMIA_CheckIt, TRUE,
+ PMIA_SubMenu, submenu,
+ TAG_DONE),
+ ~0);
+ }
+
+ submenu = NewObject(NULL, "popupmenu.class", TAG_DONE);
+ smenu = currentmenu;
+ currentmenu = submenu;
+ n = 0;
+ }
+
+ if(i >= AMI_SELECTMENU_MAX) break;
+ }
+
+ if((submenu != NULL) && (n != 0)) {
+ /* attach the previous submenu */
+ IDoMethod(smenu, PM_INSERT,
+ NewObject(NULL, "popupmenuitem.class",
+ PMIA_Title, more_label,
+ PMIA_CheckIt, TRUE,
+ PMIA_SubMenu, submenu,
+ TAG_DONE),
+ ~0);
+ }
+
+ ami_set_pointer(g->shared, GUI_POINTER_DEFAULT, false); // Clear the menu-style
pointer
+
+ IDoMethod(selectmenuobj, PM_OPEN, g->shared->win);
+
+ /* PM_OPEN is blocking, so dispose menu immediately... */
+ if(selectmenuobj) DisposeObject(selectmenuobj);
+
+ /* ...and get rid of popupmenu.class ASAP */
+ if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu);
+ if(PopupMenuBase) CloseLibrary(PopupMenuBase);
+
+ /* Free the menu labels */
+ if(more_label) ami_utf8_free(more_label);
+ for(i = 0; i < AMI_SELECTMENU_MAX; i++) {
+ if(selectmenu_item[i] != NULL) {
+ ami_utf8_free(selectmenu_item[i]);
+ selectmenu_item[i] = NULL;
+ }
+ }
+}
+
+#else
+#include "amiga/selectmenu.h"
+void gui_create_form_select_menu(struct gui_window *g, struct form_control *control)
+{
+}
+
+BOOL ami_selectmenu_is_safe()
+{
+ return FALSE;
+}
+#endif
+
diff --git a/amiga/context_menu.h b/amiga/selectmenu.h
similarity index 74%
rename from amiga/context_menu.h
rename to amiga/selectmenu.h
index 5697b56..f55b6ca 100755
--- a/amiga/context_menu.h
+++ b/amiga/selectmenu.h
@@ -16,20 +16,24 @@
* along with this program. If not, see <
http://www.gnu.org/licenses/>.
*/
-#ifndef AMIGA_CONTEXT_MENU_H
-#define AMIGA_CONTEXT_MENU_H
+#ifndef AMIGA_SELECTMENU_H
+#define AMIGA_SELECTMENU_H
+
+#include <exec/types.h>
-struct tree;
struct gui_window;
-struct gui_window_2;
struct form_control;
-void ami_context_menu_init(void);
-void ami_context_menu_free(void);
-BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap);
-void ami_context_menu_show(struct gui_window_2 *gwin, int x, int y);
+BOOL popupmenu_lib_ok;
void gui_create_form_select_menu(struct gui_window *g, struct form_control *control);
+/**
+ * Opens popupmenu.library to check the version.
+ * Versions older than 53.11 are dangerous!
+ *
+ * \returns TRUE if popupmenu is safe, FALSE otherwise.
+ */
+BOOL ami_selectmenu_is_safe(void);
#endif
diff --git a/amiga/tree.c b/amiga/tree.c
index 5e05db2..6f363e7 100644
--- a/amiga/tree.c
+++ b/amiga/tree.c
@@ -889,22 +889,23 @@ void ami_tree_close(struct treeview_window *twin)
ami_free_layers(&twin->globals);
ami_plot_release_pens(&twin->shared_pens);
- for(i=0;i<AMI_TREE_MENU_ITEMS;i++)
- {
- if(twin->menu_name[i] && (twin->menu_name[i] != NM_BARLABEL))
ami_utf8_free(twin->menu_name[i]);
+ for(i=0;i<AMI_TREE_MENU_ITEMS;i++) {
+ if(twin->menu_name[i] && (twin->menu_name[i] != NM_BARLABEL))
+ ami_utf8_free(twin->menu_name[i]);
}
+
FreeVec(twin->menu);
twin->menu = NULL;
ami_utf8_free(twin->wintitle);
- if(twin->type == AMI_TREE_SSLCERT)
- {
+ if(twin->type == AMI_TREE_SSLCERT) {
ami_utf8_free(twin->sslerr);
ami_utf8_free(twin->sslaccept);
ami_utf8_free(twin->sslreject);
ami_ssl_free(twin);
}
-
- ami_gui_hotlist_update_all();
+
+ if(twin->type == AMI_TREE_SSLCERT)
+ ami_gui_hotlist_update_all();
}
static void ami_tree_update_quals(struct treeview_window *twin)
diff --git a/beos/Makefile.target b/beos/Makefile.target
index 23d8ccb..8759d08 100644
--- a/beos/Makefile.target
+++ b/beos/Makefile.target
@@ -16,8 +16,8 @@ LDFLAGS += -lexpat -lcurl
COMMON_WARNFLAGS += -Wno-multichar
# compiler flags
-CFLAGS += -Dnsbeos -D_BSD_SOURCE -D_POSIX_C_SOURCE -Drestrict="" -g -O0
-CXXFLAGS += -Dnsbeos -D_BSD_SOURCE -D_POSIX_C_SOURCE -Drestrict="" -g -O0
+CFLAGS += -std=c99 -Dnsbeos -D_BSD_SOURCE -D_POSIX_C_SOURCE -Drestrict="" -g
+CXXFLAGS += -Dnsbeos -D_BSD_SOURCE -D_POSIX_C_SOURCE -Drestrict="" -g
BEOS_BERES := beres
BEOS_RC := rc
@@ -114,6 +114,7 @@ EXETARGET := NetSurf
# The filter and target for split messages
MESSAGES_FILTER=beos
+MESSAGES_TARGET=beos/res
# ----------------------------------------------------------------------------
# Resources
diff --git a/beos/about.cpp b/beos/about.cpp
index 7db7145..89eb818 100644
--- a/beos/about.cpp
+++ b/beos/about.cpp
@@ -32,7 +32,7 @@ extern "C" {
#include "beos/scaffolding.h"
#include "beos/window.h"
-#include <Alert.h>
+#include <private/interface/AboutWindow.h>
#include <Application.h>
#include <Invoker.h>
#include <String.h>
@@ -50,30 +50,8 @@ void nsbeos_about(struct gui_window *gui)
text << "Date : " << WT_COMPILEDATE << "\n";
text << "cURL : " << LIBCURL_VERSION << "\n";
- BAlert *alert = new BAlert("about", text.String(), "Credits",
"Licence", "Ok");
-
- BHandler *target = be_app;
- BMessage *message = new BMessage(ABOUT_BUTTON);
- BInvoker *invoker = NULL;
- if (gui) {
- nsbeos_scaffolding *s = nsbeos_get_scaffold(gui);
- if (s) {
- NSBrowserWindow *w = nsbeos_get_bwindow_for_scaffolding(s);
- if (w) {
- alert->SetFeel(B_MODAL_SUBSET_WINDOW_FEEL);
- alert->AddToSubset(w);
- }
- NSBaseView *v = nsbeos_get_baseview_for_scaffolding(s);
- if (v) {
- if (w)
- message->AddPointer("Window", w);
- target = v;
- }
- }
- }
- invoker = new BInvoker(message, target);
-
+ BAboutWindow *alert = new BAboutWindow("About NetSurf",
"application/x-vnd.NetSurf");
+ alert->AddExtraInfo(text);
+ alert->Show();
//TODO: i18n-ize
-
- alert->Go(invoker);
}
diff --git a/beos/bitmap.cpp b/beos/bitmap.cpp
index 3228770..b39da7c 100644
--- a/beos/bitmap.cpp
+++ b/beos/bitmap.cpp
@@ -538,19 +538,19 @@ static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle
*content)
static struct gui_bitmap_table bitmap_table = {
- .create = bitmap_create,
- .destroy = bitmap_destroy,
- .set_opaque = bitmap_set_opaque,
- .get_opaque = bitmap_get_opaque,
- .test_opaque = bitmap_test_opaque,
- .get_buffer = bitmap_get_buffer,
- .get_rowstride = bitmap_get_rowstride,
- .get_width = bitmap_get_width,
- .get_height = bitmap_get_height,
- .get_bpp = bitmap_get_bpp,
- .save = bitmap_save,
- .modified = bitmap_modified,
- .render = bitmap_render,
+ /*.create =*/ bitmap_create,
+ /*.destroy =*/ bitmap_destroy,
+ /*.set_opaque =*/ bitmap_set_opaque,
+ /*.get_opaque =*/ bitmap_get_opaque,
+ /*.test_opaque =*/ bitmap_test_opaque,
+ /*.get_buffer =*/ bitmap_get_buffer,
+ /*.get_rowstride =*/ bitmap_get_rowstride,
+ /*.get_width =*/ bitmap_get_width,
+ /*.get_height =*/ bitmap_get_height,
+ /*.get_bpp =*/ bitmap_get_bpp,
+ /*.save =*/ bitmap_save,
+ /*.modified =*/ bitmap_modified,
+ /*.render =*/ bitmap_render,
};
struct gui_bitmap_table *beos_bitmap_table = &bitmap_table;
diff --git a/beos/gui.cpp b/beos/gui.cpp
index 5eabfa8..cfd026b 100644
--- a/beos/gui.cpp
+++ b/beos/gui.cpp
@@ -38,6 +38,7 @@
#include <Mime.h>
#include <Path.h>
#include <PathFinder.h>
+#include <Resources.h>
#include <Roster.h>
#include <Screen.h>
#include <String.h>
@@ -81,8 +82,6 @@ extern "C" {
#include "beos/scaffolding.h"
#include "beos/bitmap.h"
-static void *myrealloc(void *ptr, size_t len, void *pw);
-
//TODO: use resources
// enable using resources instead of files
#define USE_RESOURCES 1
@@ -550,7 +549,7 @@ static void gui_init(int argc, char** argv)
#define STROF(n) #n
#define FIND_THROB(n) filenames[(n)] = \
"throbber/throbber" STROF(n) ".png";
- char *filenames[9];
+ const char *filenames[9];
FIND_THROB(0);
FIND_THROB(1);
FIND_THROB(2);
@@ -609,6 +608,10 @@ static void gui_init(int argc, char** argv)
nsbeos_options_init();
+ /* We don't yet have an implementation of "select" form elements (they
should use a popup menu)
+ * So we use the cross-platform code instead. */
+ nsoption_set_bool(core_select_menu, true);
+
if (nsoption_charp(cookie_file) == NULL) {
find_resource(buf, "Cookies", "%/Cookies");
LOG("Using '%s' as Cookies file", buf);
@@ -691,9 +694,7 @@ void nsbeos_pipe_message(BMessage *message, BView *_this, struct
gui_window *gui
message->AddPointer("View", _this);
if (gui)
message->AddPointer("gui_window", gui);
- int len = write(sEventPipe[1], &message, sizeof(void *));
- //LOG("nsbeos_pipe_message: %d written", len);
- //printf("nsbeos_pipe_message: %d written\n", len);
+ write(sEventPipe[1], &message, sizeof(void *));
}
@@ -707,9 +708,7 @@ void nsbeos_pipe_message_top(BMessage *message, BWindow *_this, struct
beos_scaf
message->AddPointer("Window", _this);
if (scaffold)
message->AddPointer("scaffolding", scaffold);
- int len = write(sEventPipe[1], &message, sizeof(void *));
- //LOG("nsbeos_pipe_message: %d written", len);
- //printf("nsbeos_pipe_message: %d written\n", len);
+ write(sEventPipe[1], &message, sizeof(void *));
}
@@ -948,33 +947,17 @@ void die(const char * const error)
exit(EXIT_FAILURE);
}
-static void nsbeos_create_ssl_verify_window(struct browser_window *bw,
- hlcache_handle *c, const struct ssl_cert_info *certs,
- unsigned long num)
-{
- CALLED();
-}
-
-static void *myrealloc(void *ptr, size_t len, void *pw)
-{
- if (len == 0) {
- free(ptr);
- return NULL;
- }
-
- return realloc(ptr, len);
-}
-
-
static struct gui_clipboard_table beos_clipboard_table = {
gui_get_clipboard,
gui_set_clipboard,
};
static struct gui_fetch_table beos_fetch_table = {
- fetch_filetype,
- gui_get_resource_url,
- NULL //fetch_mimetype
+ fetch_filetype,
+ gui_get_resource_url,
+ NULL, // ???
+ NULL, // release_resource_data
+ NULL, // fetch_mimetype
};
static struct gui_browser_table beos_browser_table = {
@@ -982,7 +965,9 @@ static struct gui_browser_table beos_browser_table = {
gui_quit,
gui_launch_url,
NULL, //cert_verify
- gui_401login_open
+ gui_401login_open,
+ NULL, // warning
+ NULL, // pdf_password (if we have Haru support)
};
@@ -1034,8 +1019,21 @@ int main(int argc, char** argv)
nsoption_commandline(&argc, argv, NULL);
/* common initialisation */
- BPath messages = get_messages_path();
+ BResources resources;
+ resources.SetToImage((const void*)main);
+ size_t size = 0;
+
+ char path[12];
+ sprintf(path,"%.2s/Messages", getenv("LC_MESSAGES"));
+ fprintf(stderr, "Loading messages from resource %s\n", path);
+
+ const uint8_t* res = (const uint8_t*)resources.LoadResource('data', path,
&size);
+ if (size > 0 && res != NULL) {
+ ret = messages_add_from_inline(res, size);
+ } else {
+ BPath messages = get_messages_path();
ret = messages_add_from_file(messages.Path());
+ }
ret = netsurf_init(NULL);
if (ret != NSERROR_OK) {
diff --git a/beos/res/messages b/beos/res/messages
deleted file mode 120000
index f4a4d2b..0000000
--- a/beos/res/messages
+++ /dev/null
@@ -1 +0,0 @@
-../../!NetSurf/Resources/en/Messages
\ No newline at end of file
diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp
index b64bdca..2c5d4e9 100644
--- a/beos/scaffolding.cpp
+++ b/beos/scaffolding.cpp
@@ -98,7 +98,9 @@ struct beos_scaffolding {
BPopUpMenu *popup_menu;
+#ifdef ENABLE_DRAGGER
BDragger *dragger;
+#endif
BView *tool_bar;
@@ -482,6 +484,7 @@ NSBaseView::MessageReceived(BMessage *message)
case HELP_OPEN_GUIDE:
case HELP_OPEN_INFORMATION:
case HELP_OPEN_ABOUT:
+ case HELP_OPEN_LICENCE:
case HELP_LAUNCH_INTERACTIVE:
case HISTORY_SHOW_LOCAL:
case HISTORY_SHOW_GLOBAL:
@@ -549,7 +552,6 @@ NSBaseView::MessageReceived(BMessage *message)
case TOOLBAR_THROBBER:
case TOOLBAR_EDIT:
case CHOICES_SHOW:
- case ABOUT_BUTTON:
case APPLICATION_QUIT:
if (Window())
Window()->DetachCurrentMessage();
@@ -670,7 +672,9 @@ NSBaseView::AllAttached()
g->throbber->SetViewColor(c);
g->scroll_view->SetViewColor(c);
+#ifdef ENABLE_DRAGGER
g->dragger->SetViewColor(c);
+#endif
g->status_bar->SetViewColor(c);
g->status_bar->SetLowColor(c);
@@ -805,7 +809,9 @@ static void nsbeos_scaffolding_update_colors(nsbeos_scaffolding *g)
g->throbber->SetViewColor(c);
g->scroll_view->SetViewColor(c);
+#ifdef ENABLE_DRAGGER
g->dragger->SetViewColor(c);
+#endif
g->status_bar->SetViewColor(c);
g->status_bar->SetLowColor(c);
@@ -937,7 +943,6 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold,
BMessage *m
break;
case B_NETPOSITIVE_OPEN_URL:
{
- int32 i;
BString url;
if (message->FindString("be:url", &url) < B_OK)
break;
@@ -1097,6 +1102,40 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding
*scaffold, BMessage *m
case HELP_OPEN_INFORMATION:
break;
case HELP_OPEN_ABOUT:
+ {
+ const char *goto_url = "about:credits";
+ nserror nserr;
+ nsurl *url;
+ nserr = nsurl_create(goto_url, &url);
+ if (nserr == NSERROR_OK) {
+ nserr = browser_window_navigate(bw,
+ url, NULL,
+ (browser_window_nav_flags)(BW_NAVIGATE_HISTORY),
+ NULL, NULL, NULL);
+ nsurl_unref(url);
+ }
+ if (nserr != NSERROR_OK) {
+ warn_user(messages_get_errorcode(nserr), 0);
+ }
+ }
+ break;
+ case HELP_OPEN_LICENCE:
+ {
+ const char *goto_url = "about:licence";
+ nserror nserr;
+ nsurl *url;
+ nserr = nsurl_create(goto_url, &url);
+ if (nserr == NSERROR_OK) {
+ nserr = browser_window_navigate(bw,
+ url, NULL,
+ (browser_window_nav_flags)(BW_NAVIGATE_HISTORY),
+ NULL, NULL, NULL);
+ nsurl_unref(url);
+ }
+ if (nserr != NSERROR_OK) {
+ warn_user(messages_get_errorcode(nserr), 0);
+ }
+ }
break;
case HELP_LAUNCH_INTERACTIVE:
break;
@@ -1242,43 +1281,6 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding
*scaffold, BMessage *m
break;
case CHOICES_SHOW:
break;
- case ABOUT_BUTTON:
- /* XXX: doesn't work yet! bug in rsrc:/
- BString url("rsrc:/about.en.html,text/html");
- browser_window_create(url.String(), NULL, NULL, true, false);
- */
- {
- int32 button;
- if (message->FindInt32("which", &button) == B_OK) {
- const char *goto_url = NULL;
- nserror nserr;
- nsurl *url;
- switch (button) {
- case 0:
- goto_url = "about:credits";
- break;
- case 1:
- goto_url = "about:licence";
- break;
- default:
- break;
- }
- if (goto_url == NULL)
- break;
- nserr = nsurl_create(goto_url, &url);
- if (nserr == NSERROR_OK) {
- nserr = browser_window_navigate(bw,
- url, NULL,
- (browser_window_nav_flags)(BW_NAVIGATE_HISTORY),
- NULL, NULL, NULL);
- nsurl_unref(url);
- }
- if (nserr != NSERROR_OK) {
- warn_user(messages_get_errorcode(nserr), 0);
- }
- }
- }
- break;
case APPLICATION_QUIT:
nsbeos_done = true;
break;
@@ -1708,7 +1710,6 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
g->window->AddChild(g->menu_bar);
BMenu *menu;
- BMenu *submenu;
BMenuItem *item;
// App menu
@@ -1717,10 +1718,11 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
menu = new BMenu(messages_get("NetSurf"));
g->menu_bar->AddItem(menu);
- message = new BMessage(NO_ACTION);
- item = make_menu_item("Info", message);
+ message = new BMessage(B_ABOUT_REQUESTED);
+ item = make_menu_item("Info", message, true);
menu->AddItem(item);
+#if 0
message = new BMessage(NO_ACTION);
item = make_menu_item("AppHelp", message);
menu->AddItem(item);
@@ -1735,6 +1737,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
message = new BMessage(CHOICES_SHOW);
item = make_menu_item("Choices", message);
menu->AddItem(item);
+#endif
message = new BMessage(APPLICATION_QUIT);
item = make_menu_item("Quit", message, true);
@@ -1745,16 +1748,17 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
menu = new BMenu(messages_get("Page"));
g->menu_bar->AddItem(menu);
+#if 0
message = new BMessage(BROWSER_PAGE_INFO);
item = make_menu_item("PageInfo", message);
menu->AddItem(item);
message = new BMessage(BROWSER_SAVE);
- item = make_menu_item("Save", message);
+ item = make_menu_item("SaveAsNS", message);
menu->AddItem(item);
message = new BMessage(BROWSER_SAVE_COMPLETE);
- item = make_menu_item("SaveComp", message);
+ item = make_menu_item("SaveCompNS", message);
menu->AddItem(item);
submenu = new BMenu(messages_get("Export"));
@@ -1767,7 +1771,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
*/
message = new BMessage(BROWSER_EXPORT_TEXT);
- item = make_menu_item("Text", message);
+ item = make_menu_item("LinkText", message);
submenu->AddItem(item);
@@ -1781,17 +1785,19 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
message = new BMessage(BROWSER_PRINT);
- item = make_menu_item("Print", message);
+ item = make_menu_item("PrintNS", message);
menu->AddItem(item);
+#endif
message = new BMessage(BROWSER_NEW_WINDOW);
- item = make_menu_item("NewWindow", message, true);
+ item = make_menu_item("NewWindowNS", message, true);
menu->AddItem(item);
message = new BMessage(BROWSER_VIEW_SOURCE);
item = make_menu_item("ViewSrc", message, true);
menu->AddItem(item);
+#if 0 // FIXME This is supposed to be a popup menu!
// Object menu
menu = new BMenu(messages_get("Object"));
@@ -1809,6 +1815,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
message = new BMessage(BROWSER_OBJECT_RELOAD);
item = make_menu_item("ObjReload", message);
menu->AddItem(item);
+#endif
// Navigate menu
@@ -1839,6 +1846,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
item = make_menu_item("Stop", message, true);
menu->AddItem(item);
+#if 0
// View menu
menu = new BMenu(messages_get("View"));
@@ -1910,7 +1918,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
submenu->AddItem(item);
message = new BMessage(HOTLIST_SHOW);
- item = make_menu_item("HotlistShow", message);
+ item = make_menu_item("HotlistShowNS", message);
submenu->AddItem(item);
@@ -1960,6 +1968,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
message = new BMessage(BROWSER_WINDOW_RESET);
item = make_menu_item("WindowReset", message);
submenu->AddItem(item);
+#endif
// Help menu
@@ -1967,6 +1976,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
menu = new BMenu(messages_get("Help"));
g->menu_bar->AddItem(menu);
+#if 0
message = new BMessage(HELP_OPEN_CONTENTS);
item = make_menu_item("HelpContent", message);
menu->AddItem(item);
@@ -1978,14 +1988,21 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
message = new BMessage(HELP_OPEN_INFORMATION);
item = make_menu_item("HelpInfo", message);
menu->AddItem(item);
+#endif
message = new BMessage(HELP_OPEN_ABOUT);
- item = make_menu_item("HelpAbout", message);
+ item = make_menu_item("HelpCredits", message, true);
+ menu->AddItem(item);
+
+ message = new BMessage(HELP_OPEN_LICENCE);
+ item = make_menu_item("HelpLicence", message, true);
menu->AddItem(item);
+#if 0
message = new BMessage(HELP_LAUNCH_INTERACTIVE);
item = make_menu_item("HelpInter", message);
menu->AddItem(item);
+#endif
// the base view that receives the toolbar, statusbar and top-level view.
rect = frame.OffsetToCopy(0,0);
@@ -2005,6 +2022,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
g->popup_menu = new BPopUpMenu("");
+#ifdef ENABLE_DRAGGER
// the dragger to allow replicating us
// XXX: try to stuff it in the status bar at the bottom
// (BDragger *must* be a parent, sibiling or direct child of NSBaseView!)
@@ -2016,6 +2034,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
g->top_view->AddChild(g->dragger);
g->dragger->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
g->dragger->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)) ;
+#endif
// tool_bar
// the toolbar is also the dragger for now
@@ -2025,7 +2044,11 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window
*toplevel)
// but causes flicker
rect = g->top_view->Bounds();
rect.bottom = rect.top + TOOLBAR_HEIGHT - 1;
+#ifdef ENABLE_DRAGGER
rect.right = rect.right - DRAGGER_WIDTH;
+#else
+ rect.right = rect.right + 1;
+#endif
g->tool_bar = new BBox(rect, "Toolbar",
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS
| B_FULL_UPDATE_ON_RESIZE | B_NAVIGABLE_JUMP, B_PLAIN_BORDER);
diff --git a/beos/scaffolding.h b/beos/scaffolding.h
index 61d0691..5d59073 100644
--- a/beos/scaffolding.h
+++ b/beos/scaffolding.h
@@ -87,6 +87,7 @@ typedef enum {
HELP_OPEN_GUIDE,
HELP_OPEN_INFORMATION,
HELP_OPEN_ABOUT,
+ HELP_OPEN_LICENCE,
HELP_LAUNCH_INTERACTIVE,
/* history actions */
@@ -176,7 +177,6 @@ typedef enum {
/* misc actions */
CHOICES_SHOW,
- ABOUT_BUTTON,
APPLICATION_QUIT,
} menu_action;
diff --git a/content/fetch.h b/content/fetch.h
index 529a800..3c1f1cc 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -37,6 +37,7 @@ typedef enum {
FETCH_HEADER,
FETCH_DATA,
FETCH_FINISHED,
+ FETCH_TIMEDOUT,
FETCH_ERROR,
FETCH_REDIRECT,
FETCH_NOTMODIFIED,
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index a2c6f2e..4f5da3c 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -973,11 +973,19 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
msg.data.cert_err.num_certs = i;
fetch_send_callback(&msg, f->fetch_handle);
} else if (error) {
- if (result != CURLE_SSL_CONNECT_ERROR) {
+ switch (result) {
+ case CURLE_SSL_CONNECT_ERROR:
+ msg.type = FETCH_SSL_ERR;
+ break;
+
+ case CURLE_OPERATION_TIMEDOUT:
+ msg.type = FETCH_TIMEDOUT;
+ msg.data.error = curl_easy_strerror(result);
+ break;
+
+ default:
msg.type = FETCH_ERROR;
msg.data.error = curl_easy_strerror(result);
- } else {
- msg.type = FETCH_SSL_ERR;
}
fetch_send_callback(&msg, f->fetch_handle);
@@ -998,6 +1006,44 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
CURLMcode codem;
CURLMsg *curl_msg;
+ if (nsoption_bool(suppress_curl_debug) == false) {
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd = -1;
+ int i;
+
+ FD_ZERO(&read_fd_set);
+ FD_ZERO(&write_fd_set);
+ FD_ZERO(&exc_fd_set);
+
+ codem = curl_multi_fdset(fetch_curl_multi,
+ &read_fd_set, &write_fd_set,
+ &exc_fd_set, &max_fd);
+ assert(codem == CURLM_OK);
+
+ LOG("Curl file descriptor states (maxfd=%i):", max_fd);
+ for (i = 0; i <= max_fd; i++) {
+ bool read = false;
+ bool write = false;
+ bool error = false;
+
+ if (FD_ISSET(i, &read_fd_set)) {
+ read = true;
+ }
+ if (FD_ISSET(i, &write_fd_set)) {
+ write = true;
+ }
+ if (FD_ISSET(i, &exc_fd_set)) {
+ error = true;
+ }
+ if (read || write || error) {
+ LOG(" fd %*i: %s %s %s", max_fd / 10 + 1, i,
+ read ? "read" : " ",
+ write ? "write" : " ",
+ error ? "error" : " ");
+ }
+ }
+ }
+
/* do any possible work on the current fetches */
do {
codem = curl_multi_perform(fetch_curl_multi, &running);
@@ -1302,7 +1348,7 @@ nserror fetch_curl_register(void)
SETOPT(CURLOPT_LOW_SPEED_LIMIT, 1L);
SETOPT(CURLOPT_LOW_SPEED_TIME, 180L);
SETOPT(CURLOPT_NOSIGNAL, 1L);
- SETOPT(CURLOPT_CONNECTTIMEOUT, 30L);
+ SETOPT(CURLOPT_CONNECTTIMEOUT, nsoption_uint(curl_fetch_timeout));
if (nsoption_charp(ca_bundle) &&
strcmp(nsoption_charp(ca_bundle), "")) {
diff --git a/content/llcache.c b/content/llcache.c
index 851dbbb..e95eefb 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -120,6 +120,8 @@ typedef struct {
uint32_t redirect_count; /**< Count of redirects followed */
+ uint32_t retries_remaining; /**< Number of times to retry on timeout */
+
bool tried_with_auth; /**< Whether we've tried with auth */
bool tried_with_tls_downgrade; /**< Whether we've tried TLS <= 1.0 */
@@ -227,6 +229,9 @@ struct llcache_s {
/** The target upper bound for the RAM cache size */
uint32_t limit;
+ /** The number of fetch attempts we make when timing out */
+ uint32_t fetch_attempts;
+
/** Whether or not our users are caught up */
bool all_caught_up;
@@ -909,6 +914,7 @@ static nserror llcache_object_fetch(llcache_object *object, uint32_t
flags,
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
+ object->fetch.retries_remaining = llcache->fetch_attempts;
return llcache_object_refetch(object);
}
@@ -2653,6 +2659,18 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
break;
/* Out-of-band information */
+ case FETCH_TIMEDOUT:
+ /* Timed out while trying to fetch. */
+ /* The fetch has already been cleaned up by the fetcher but
+ * we would like to retry if we can. */
+ if (object->fetch.retries_remaining > 1) {
+ object->fetch.retries_remaining--;
+ error = llcache_object_refetch(object);
+ break;
+ }
+ /* Otherwise fall through to error, setting the message to
+ * a timeout
+ */
case FETCH_ERROR:
/* An error occurred while fetching */
/* The fetch has has already been cleaned up by the fetcher */
@@ -3303,6 +3321,7 @@ llcache_initialise(const struct llcache_parameters *prm)
llcache->minimum_bandwidth = prm->minimum_bandwidth;
llcache->maximum_bandwidth = prm->maximum_bandwidth;
llcache->time_quantum = prm->time_quantum;
+ llcache->fetch_attempts = prm->fetch_attempts;
llcache->all_caught_up = true;
LOG("llcache initialising with a limit of %d bytes", llcache->limit);
diff --git a/content/llcache.h b/content/llcache.h
index 1b7ba7d..cce9a79 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -230,6 +230,9 @@ struct llcache_parameters {
*/
unsigned long time_quantum;
+ /** The number of fetches to attempt when timing out */
+ uint32_t fetch_attempts;
+
struct llcache_store_parameters store;
};
diff --git a/desktop/browser.c b/desktop/browser.c
index 21b6c88..80bf65a 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -106,7 +106,6 @@ static inline void browser_window_get_scrollbar_pos(struct
browser_window *bw,
* \param horizontal Whether to get length of horizontal scrollbar
* \return the scrollbar's length
*/
-
static inline int browser_window_get_scrollbar_len(struct browser_window *bw,
bool horizontal)
{
@@ -116,6 +115,42 @@ static inline int browser_window_get_scrollbar_len(struct
browser_window *bw,
return bw->height;
}
+
+/* exported interface, documented in browser.h */
+nserror
+browser_window_get_name(struct browser_window *bw, const char **out_name)
+{
+ assert(bw != NULL);
+
+ *out_name = bw->name;
+
+ return NSERROR_OK;
+}
+
+/* exported interface, documented in browser.h */
+nserror
+browser_window_set_name(struct browser_window *bw, const char *name)
+{
+ char *nname = NULL;
+
+ assert(bw != NULL);
+
+ if (name != NULL) {
+ nname = strdup(name);
+ if (nname == NULL) {
+ return NSERROR_NOMEM;
+ }
+ }
+
+ if (bw->name != NULL) {
+ free(bw->name);
+ }
+
+ bw->name = nname;
+
+ return NSERROR_OK;
+}
+
/* exported interface, documented in browser.h */
bool browser_window_redraw(struct browser_window *bw, int x, int y,
const struct rect *clip, const struct redraw_context *ctx)
@@ -1714,6 +1749,15 @@ static void browser_window_destroy_internal(struct browser_window
*bw)
browser_window_destroy_children(bw);
}
+ /* Destroy scrollbars */
+ if (bw->scroll_x != NULL) {
+ scrollbar_destroy(bw->scroll_x);
+ }
+
+ if (bw->scroll_y != NULL) {
+ scrollbar_destroy(bw->scroll_y);
+ }
+
/* clear any pending callbacks */
guit->browser->schedule(-1, browser_window_refresh, bw);
/* The ugly cast here is so the reformat function can be
diff --git a/desktop/browser.h b/desktop/browser.h
index 07faf10..a1ec37a 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -677,11 +677,39 @@ int browser_get_dpi(void);
nserror browser_window_debug_dump(struct browser_window *bw, FILE *f, enum content_debug
op);
/**
- * set debug options on a window
+ * Set debug options on a window
+ *
* \param bw The browser window.
* \param op The debug operation type.
* \return NSERROR_OK on success or error code on faliure.
*/
nserror browser_window_debug(struct browser_window *bw, enum content_debug op);
+/**
+ * Obtain a browsing contexts name.
+ *
+ * The returned pointer is owned bu the browsing context and is only
+ * valid untill the next operation on that context.
+ * The returned name may be NULL if no name has been set.
+ * \todo This does not consider behaviour wrt frames
+ *
+ * \param bw The browser window.
+ * \param name recives result string.
+ * \return NSERROR_OK
+ */
+nserror browser_window_get_name(struct browser_window *bw, const char **name);
+
+/**
+ * Set a browsing contexts name.
+ *
+ * Changes a browsing contexts name to a copy of that passed and the
+ * value is not subsequently referenced.
+ *
+ * \param bw The browser window.
+ * \param name The name string to set.
+ * \return NSERROR_OK and the name is updated or NSERROR_NOMEM and the
+ * original name is untouched.
+ */
+nserror browser_window_set_name(struct browser_window *bw, const char *name);
+
#endif
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 0fd7b7b..d6b5abe 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -164,6 +164,9 @@ nserror netsurf_init(const char *store_path)
LOG("Setting minimum memory cache size %zd",
hlcache_parameters.llcache.limit);
}
+ /* Set up the max attempts made to fetch a timing out resource */
+ hlcache_parameters.llcache.fetch_attempts = nsoption_uint(max_retried_fetches);
+
/* image cache is 25% of total memory cache size */
image_cache_parameters.limit = (hlcache_parameters.llcache.limit * 25) / 100;
diff --git a/desktop/options.h b/desktop/options.h
index 33ecb75..e734c52 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -185,6 +185,9 @@ NSOPTION_UINT(min_reflow_period, DEFAULT_REFLOW_PERIOD)
/* use core selection menu */
NSOPTION_BOOL(core_select_menu, false)
+/* display decoded international domain names */
+NSOPTION_BOOL(display_decoded_idn, false)
+
/******** Fetcher options ********/
/** Maximum simultaneous active fetchers */
@@ -205,6 +208,14 @@ NSOPTION_INTEGER(max_fetchers_per_host, 5)
*/
NSOPTION_INTEGER(max_cached_fetch_handles, 6)
+/** Number of times to retry timed-out fetches before giving up. */
+NSOPTION_UINT(max_retried_fetches, 3)
+
+/** Number of seconds to allow for a DNS-resolution+connect() before timing out
+ * the cURL socket.
+ */
+NSOPTION_UINT(curl_fetch_timeout, 10)
+
/** Suppress debug output from cURL. */
NSOPTION_BOOL(suppress_curl_debug, true)
diff --git a/framebuffer/res/fonts/glyph_data b/framebuffer/res/fonts/glyph_data
index c4bb2b1..e027566 100644
--- a/framebuffer/res/fonts/glyph_data
+++ b/framebuffer/res/fonts/glyph_data
@@ -4452,6 +4452,25 @@ U+010C - LATIN CAPITAL LETTER C WITH CARON
........ ........ ........ ........
........ ........ ........ ........
-----------------------------------------------------
+U+010D - LATIN SMALL LETTER C WITH CARON
+- - - - - - - - - - - - - - - - - - - - - - - - - - -
+ ........ ........ ........ ........
+ ##...##. .##...## ###.###. .###.###
+ .##.##.. ..##.##. .#####.. ..#####.
+ ..###... ...###.. ..###... ...###..
+ ........ ........ ........ ........
+ .#####.. ..####.. .#####.. ..####..
+ #######. .######. #######. .######.
+ ##...##. .##..##. ###.###. ###.###.
+ ##...... ##...... ###..... ###.....
+ ##...... ##...... ###..... ###.....
+ ##...##. ##..##.. ###.###. ###.###.
+ #######. ######.. #######. #######.
+ .#####.. .####... .#####.. .#####..
+ ........ ........ ........ ........
+ ........ ........ ........ ........
+ ........ ........ ........ ........
+-----------------------------------------------------
U+0141 - LATIN CAPITAL LETTER L WITH STROKE
- - - - - - - - - - - - - - - - - - - - - - - - - - -
........ ........ ........ ........
@@ -4528,21 +4547,21 @@ U+0144 - LATIN SMALL LETTER N WITH ACUTE
........ ........ ........ ........
........ ........ ........ ........
-----------------------------------------------------
-U+010D - LATIN SMALL LETTER C WITH CARON
+U+014D - LATIN SMALL LETTER O WITH MACRON
- - - - - - - - - - - - - - - - - - - - - - - - - - -
........ ........ ........ ........
- ##...##. .##...## ###.###. .###.###
- .##.##.. ..##.##. .#####.. ..#####.
- ..###... ...###.. ..###... ...###..
+ ........ ........ ........ ........
+ .######. ...##### #######. ..######
+ .######. ..#####. #######. .######.
........ ........ ........ ........
.#####.. ..####.. .#####.. ..####..
#######. .######. #######. .######.
##...##. .##..##. ###.###. ###.###.
- ##...... ##...... ###..... ###.....
- ##...... ##...... ###..... ###.....
+ ##...##. .##..##. ###.###. ###.###.
##...##. ##..##.. ###.###. ###.###.
- #######. ######.. #######. #######.
- .#####.. .####... .#####.. .#####..
+ ##...##. ##..##.. ###.###. ###.###.
+ #######. ######.. #######. ######..
+ .#####.. .####... .#####.. .####...
........ ........ ........ ........
........ ........ ........ ........
........ ........ ........ ........
diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c
index 4506ac2..19d5b2e 100644
--- a/gtk/scaffolding.c
+++ b/gtk/scaffolding.c
@@ -2343,10 +2343,21 @@ void nsgtk_window_set_title(struct gui_window *gw, const char
*title)
nserror gui_window_set_url(struct gui_window *gw, nsurl *url)
{
struct nsgtk_scaffolding *g;
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
g = nsgtk_get_scaffold(gw);
if (g->top_level == gw) {
- gtk_entry_set_text(GTK_ENTRY(g->url_bar), nsurl_access(url));
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
+ idn_url_s = NULL;
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(g->url_bar), idn_url_s ? idn_url_s :
nsurl_access(url));
+
+ if(idn_url_s)
+ free(idn_url_s);
+
gtk_editable_set_position(GTK_EDITABLE(g->url_bar), -1);
}
return NSERROR_OK;
diff --git a/javascript/Makefile b/javascript/Makefile
index ee9c3de..36f123b 100644
--- a/javascript/Makefile
+++ b/javascript/Makefile
@@ -1,93 +1,34 @@
#
# NetSurf javascript source file inclusion
#
-# Included by Makefile.sources
+# Included by Makefile
#
-# ----------------------------------------------------------------------------
-# JSAPI binding
-# ----------------------------------------------------------------------------
-
-S_JSAPI_BINDING:=
-D_JSAPI_BINDING:=
-
-JSAPI_BINDING_htmldocument := javascript/jsapi/htmldocument.bnd
-JSAPI_BINDING_htmlelement := javascript/jsapi/htmlelement.bnd
-JSAPI_BINDING_window := javascript/jsapi/window.bnd
-JSAPI_BINDING_navigator := javascript/jsapi/navigator.bnd
-JSAPI_BINDING_console := javascript/jsapi/console.bnd
-JSAPI_BINDING_location := javascript/jsapi/location.bnd
-JSAPI_BINDING_htmlcollection := javascript/jsapi/htmlcollection.bnd
-JSAPI_BINDING_nodelist := javascript/jsapi/nodelist.bnd
-JSAPI_BINDING_text := javascript/jsapi/text.bnd
-JSAPI_BINDING_comment := javascript/jsapi/comment.bnd
-JSAPI_BINDING_node := javascript/jsapi/node.bnd
-JSAPI_BINDING_event := javascript/jsapi/event.bnd
-
-# 1: input binding file
-# 2: source output file
-# 3: header output file
-# 4: binding name
-define convert_jsapi_binding
-
-S_JSAPI_BINDING += $(2)
-D_JSAPI_BINDING += $(patsubst %.c,%.d,$(2))
-
-$(2): $(1) $(OBJROOT)/created
- $$(VQ)echo " GENBIND: $(1)"
- $(Q)nsgenbind -g -I javascript/WebIDL -d $(patsubst %.c,%.d,$(2)) -h $(3) -o $(2) $(1)
-
-$(3): $(2)
-
-endef
-
-# Javascript sources
+# Check if jsapi is required
ifeq ($(NETSURF_USE_JS),YES)
WANT_JS_SOURCE := YES
-endif
-
+else
ifeq ($(NETSURF_USE_MOZJS),YES)
WANT_JS_SOURCE := YES
endif
-
-ifeq ($(WANT_JS_SOURCE),YES)
-
-S_JSAPI :=
-
-S_JAVASCRIPT += content.c jsapi.c fetcher.c $(addprefix jsapi/,$(S_JSAPI))
-
-$(eval $(foreach V,$(filter JSAPI_BINDING_%,$(.VARIABLES)),$(call
convert_jsapi_binding,$($(V)),$(OBJROOT)/$(patsubst
JSAPI_BINDING_%,%,$(V)).c,$(OBJROOT)/$(patsubst JSAPI_BINDING_%,%,$(V)).h,$(patsubst
JSAPI_BINDING_%,%,$(V))_jsapi)))
-
-ifeq ($(filter $(MAKECMDGOALS),clean test coverage),)
--include $(D_JSAPI_BINDING)
endif
+S_JAVASCRIPT_BINDING:=
+
+ifeq ($(WANT_JS_SOURCE),YES)
+# JSAPI (spidemonkey)
+include javascript/jsapi/Makefile
else
ifeq ($(NETSURF_USE_DUKTAPE),YES)
-
-javascript/dukky.c: $(OBJROOT)/duktape/binding.h
-
-BINDINGS := $(wildcard javascript/duktape/*.bnd)
-
-$(OBJROOT)/duktape/binding.h $(OBJROOT)/duktape/Makefile: javascript/duktape/netsurf.bnd
$(BINDINGS)
- $(Q)mkdir -p $(OBJROOT)/duktape
- $(VQ)echo " GENBIND: $<"
- $(Q)nsgenbind -I javascript/WebIDL $< $(OBJROOT)/duktape
-
-ifeq ($(filter $(MAKECMDGOALS),clean test coverage),)
--include $(OBJROOT)/duktape/Makefile
-endif
-
-S_JSAPI_BINDING:=$(addprefix $(OBJROOT)/duktape/,$(NSGENBIND_SOURCES))
-
-$(S_JSAPI_BINDING): $(BINDINGS)
-
-S_JAVASCRIPT += dukky.c content.c fetcher.c duktape/duktape.c
-
-CFLAGS += -DDUK_OPT_HAVE_CUSTOM_H
+# Duktape
+include javascript/duktape/Makefile
else
-S_JAVASCRIPT += none.c fetcher.c
+# None
+include javascript/none/Makefile
endif
endif
-S_JAVASCRIPT := $(addprefix javascript/,$(S_JAVASCRIPT)) $(S_JSAPI_BINDING)
+# Fetcher for javascript scheme is always required
+S_JAVASCRIPT += fetcher.c
+
+S_JAVASCRIPT := $(addprefix javascript/,$(S_JAVASCRIPT)) $(S_JAVASCRIPT_BINDING)
diff --git a/javascript/WebIDL/Makefile b/javascript/WebIDL/Makefile
index 6319bbd..7d901ce 100644
--- a/javascript/WebIDL/Makefile
+++ b/javascript/WebIDL/Makefile
@@ -16,12 +16,13 @@
.PHONY:all clean
-all: dom.idl html.idl uievents.idl
+all: dom.idl html.idl uievents.idl cssom.idl
-.INTERMEDIATE:dom-spec.html dom-spec.xml dom-idl.html
+.INTERMEDIATE:dom-spec.html dom-spec.xml dom-idl.html
.INTERMEDIATE:html-spec.html html-spec.xml html-idl.html
.INTERMEDIATE:uievents-spec.html uievents-spec.xml uievents-idl.html
.INTERMEDIATE:urlutils-spec.html urlutils-spec.xml urlutils-idl.html
+.INTERMEDIATE:cssom-spec.html cssom-spec.xml cssom-idl.html
dom-spec.html:
curl -s
https://dom.spec.whatwg.org/ -o $@
@@ -35,8 +36,11 @@ uievents-spec.html:
urlutils-spec.html:
curl -s
https://url.spec.whatwg.org/ -o $@
+cssom-spec.html:
+ curl -s
https://drafts.csswg.org/cssom-1/ -o $@
+
%-spec.xml: %-spec.html
- -tidy -q -f $@.errors --new-blocklevel-tags
header,hgroup,figure,time,main,nav,svg,rect,text,image,mark,figcaption,section -o $@
-asxml $<
+ -tidy -q -f $@.errors --new-blocklevel-tags
header,hgroup,figure,time,main,nav,svg,rect,text,image,mark,figcaption,section,g,path,circle
-o $@ -asxml $<
%-idl.html: %-spec.xml
hxselect 'pre[class="idl"]' < $< > $@
diff --git a/javascript/WebIDL/cssom.idl b/javascript/WebIDL/cssom.idl
new file mode 100644
index 0000000..95c97e4
--- /dev/null
+++ b/javascript/WebIDL/cssom.idl
@@ -0,0 +1,157 @@
+// Retrived from
https://drafts.csswg.org/cssom-1/
+// Wed Nov 4 15:39:43 GMT 2015
+// Removed duplicate IDL from appendix
+
+
+[ArrayClass]interface MediaList {
+ [TreatNullAs=EmptyString] stringifier attribute DOMString mediaText;
+ readonly attribute unsigned long length;
+ getter DOMString? item(unsigned long index );
+ void appendMedium(DOMString medium );
+ void deleteMedium(DOMString medium );
+};
+
+interface StyleSheet {
+ readonly attribute DOMString type;
+ readonly attribute DOMString? href;
+ readonly attribute (Element or ProcessingInstruction)? ownerNode;
+ readonly attribute StyleSheet? parentStyleSheet;
+ readonly attribute DOMString? title;
+ [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
+ attribute boolean disabled;
+};
+
+interface CSSStyleSheet : StyleSheet {
+ readonly attribute CSSRule? ownerRule;
+ [SameObject] readonly attribute CSSRuleList cssRules;
+ unsigned long insertRule(DOMString rule , unsigned long index );
+ void deleteRule(unsigned long index );
+};
+
+[ArrayClass]interface StyleSheetList {
+ getter StyleSheet? item(unsigned long index );
+ readonly attribute unsigned long length;
+};
+
+partial interface Document {
+ [SameObject] readonly attribute StyleSheetList styleSheets;
+ attribute DOMString? selectedStyleSheetSet;
+ readonly attribute DOMString? lastStyleSheetSet;
+ readonly attribute DOMString? preferredStyleSheetSet;
+ readonly attribute DOMString[] styleSheetSets;
+ void enableStyleSheetsForSet(DOMString? name );
+};
+
+[NoInterfaceObject]interface LinkStyle {
+ readonly attribute StyleSheet? sheet;
+};
+
+ProcessingInstruction implements LinkStyle;
+
+[ArrayClass]interface CSSRuleList {
+ getter CSSRule? item(unsigned long index );
+ readonly attribute unsigned long length;
+};
+
+interface CSSRule {
+ const unsigned short STYLE_RULE = 1;
+ const unsigned short CHARSET_RULE = 2; // historical
+ const unsigned short IMPORT_RULE = 3;
+ const unsigned short MEDIA_RULE = 4;
+ const unsigned short FONT_FACE_RULE = 5;
+ const unsigned short PAGE_RULE = 6;
+ const unsigned short MARGIN_RULE = 9;
+ const unsigned short NAMESPACE_RULE = 10;
+ readonly attribute unsigned short type;
+ attribute DOMString cssText;
+ readonly attribute CSSRule? parentRule;
+ readonly attribute CSSStyleSheet? parentStyleSheet;
+};
+
+interface CSSStyleRule : CSSRule {
+ attribute DOMString selectorText;
+ [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
+};
+
+interface CSSImportRule : CSSRule {
+ readonly attribute DOMString href;
+ [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
+ [SameObject] readonly attribute CSSStyleSheet styleSheet;
+};
+
+interface CSSGroupingRule : CSSRule {
+ [SameObject] readonly attribute CSSRuleList cssRules;
+ unsigned long insertRule(DOMString rule , unsigned long index );
+ void deleteRule(unsigned long index );
+};
+
+interface CSSMediaRule : CSSGroupingRule {
+ [SameObject, PutForwards=mediaText] readonly attribute MediaList media ;
+};
+
+interface CSSPageRule : CSSGroupingRule {
+ attribute DOMString selectorText ;
+ [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style ;
+};
+
+interface CSSMarginRule : CSSRule {
+ readonly attribute DOMString name;
+ [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
+};
+
+interface CSSNamespaceRule : CSSRule {
+ readonly attribute DOMString namespaceURI;
+ readonly attribute DOMString prefix;
+};
+
+interface CSSStyleDeclaration {
+ attribute DOMString cssText;
+ readonly attribute unsigned long length;
+ getter DOMString item(unsigned long index );
+ DOMString getPropertyValue(DOMString property );
+ DOMString getPropertyPriority(DOMString property );
+ void setProperty(DOMString property , [TreatNullAs=EmptyString] DOMString value ,
[TreatNullAs=EmptyString] optional DOMString priority = "");
+ void setPropertyValue(DOMString property , [TreatNullAs=EmptyString] DOMString value
);
+ void setPropertyPriority(DOMString property , [TreatNullAs=EmptyString] DOMString
priority );
+ DOMString removeProperty(DOMString property );
+ readonly attribute CSSRule? parentRule;
+ [TreatNullAs=EmptyString] attribute DOMString cssFloat;
+};
+
+partial interface CSSStyleDeclaration {
+ [TreatNullAs=EmptyString] attribute DOMString _dashed_attribute ;
+};
+
+[NoInterfaceObject]interface ElementCSSInlineStyle {
+ [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
+};
+
+HTMLElement implements ElementCSSInlineStyle;
+
+SVGElement implements ElementCSSInlineStyle;
+
+partial interface Window {
+ [NewObject] CSSStyleDeclaration getComputedStyle(Element elt , optional DOMString?
pseudoElt );
+};
+
+[NoInterfaceObject]interface GetStyleUtils {
+ [SameObject] readonly attribute CSSStyleDeclaration cascadedStyle;
+ [SameObject] readonly attribute CSSStyleDeclaration defaultStyle;
+ [SameObject] readonly attribute CSSStyleDeclaration rawComputedStyle;
+ [SameObject] readonly attribute CSSStyleDeclaration usedStyle;
+};
+
+partial interface Element {
+ PseudoElement? pseudo(DOMString pseudoElt );
+};
+
+Element implements GetStyleUtils;
+
+interface PseudoElement {
+};
+
+PseudoElement implements GetStyleUtils;
+
+interface CSS {
+ static DOMString escape(DOMString ident );
+};
diff --git a/javascript/WebIDL/dom-parsing.idl b/javascript/WebIDL/dom-parsing.idl
new file mode 100644
index 0000000..d258132
--- /dev/null
+++ b/javascript/WebIDL/dom-parsing.idl
@@ -0,0 +1,35 @@
+// Retrived from
http://www.w3.org/TR/DOM-Parsing/
+// Wed Nov 4 15:39:43 GMT 2015
+// Manually extracted IDL
+
+enum SupportedType {
+ "text/html",
+ "text/xml",
+ "application/xml",
+ "application/xhtml+xml",
+ "image/svg+xml"
+};
+
+[Constructor]
+interface DOMParser {
+ [NewObject]
+ Document parseFromString (DOMString str, SupportedType type);
+};
+
+[Constructor]
+interface XMLSerializer {
+ DOMString serializeToString (Node root);
+};
+
+partial interface Element {
+ [TreatNullAs=EmptyString]
+ attribute DOMString innerHTML;
+ [TreatNullAs=EmptyString]
+ attribute DOMString outerHTML;
+ void insertAdjacentHTML (DOMString position, DOMString text);
+};
+
+partial interface Range {
+ [NewObject]
+ DocumentFragment createContextualFragment (DOMString fragment);
+};
diff --git a/javascript/WebIDL/html.idl b/javascript/WebIDL/html.idl
index 62d4967..73112f0 100644
--- a/javascript/WebIDL/html.idl
+++ b/javascript/WebIDL/html.idl
@@ -1,6 +1,6 @@
// HTML web IDL
// Retrived from
https://html.spec.whatwg.org/
-// Sat Jul 18 2015
+// Mon Oct 5 2015
typedef (Int8Array or Uint8Array or Uint8ClampedArray or
@@ -9,16 +9,16 @@ typedef (Int8Array or Uint8Array or Uint8ClampedArray or
Float32Array or Float64Array or
DataView) ArrayBufferView;
-interface HTMLAllCollection : HTMLCollection {
- // inherits length and 'getter'
- Element? item(unsigned long index);
+interface HTMLAllCollection {
+ readonly attribute unsigned long length;
+ getter Element? item(unsigned long index);
(HTMLCollection or Element)? item(DOMString name);
- legacycaller getter (HTMLCollection or Element)? namedItem(DOMString name); // shadows
inherited namedItem()
+ legacycaller getter (HTMLCollection or Element)? namedItem(DOMString name);
};
interface HTMLFormControlsCollection : HTMLCollection {
// inherits length and item()
- legacycaller getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows
inherited namedItem()
+ getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited
namedItem()
};
interface RadioNodeList : NodeList {
@@ -26,37 +26,24 @@ interface RadioNodeList : NodeList {
};
interface HTMLOptionsCollection : HTMLCollection {
- // inherits item()
+ // inherits item(), namedItem()
attribute unsigned long length; // shadows inherited length
- legacycaller HTMLOptionElement? (DOMString name);
- setter creator void (unsigned long index, HTMLOptionElement? option);
+ setter void (unsigned long index, HTMLOptionElement? option);
void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or
long)? before = null);
void remove(long index);
attribute long selectedIndex;
};
-interface HTMLPropertiesCollection : HTMLCollection {
- // inherits length and item()
- getter PropertyNodeList? namedItem(DOMString name); // shadows inherited namedItem()
- [SameObject] readonly attribute DOMString[] names;
-};
-
-typedef sequence<any> PropertyValueArray;
-
-interface PropertyNodeList : NodeList {
- PropertyValueArray getValues();
-};
-
[OverrideBuiltins, Exposed=(Window,Worker)]
interface DOMStringMap {
getter DOMString (DOMString name);
- setter creator void (DOMString name, DOMString value);
+ setter void (DOMString name, DOMString value);
deleter void (DOMString name);
};
interface DOMElementMap {
getter Element (DOMString name);
- setter creator void (DOMString name, Element value);
+ setter void (DOMString name, Element value);
deleter void (DOMString name);
};
@@ -89,7 +76,6 @@ partial /*sealed*/ interface Document {
[SameObject] readonly attribute HTMLCollection forms;
[SameObject] readonly attribute HTMLCollection scripts;
NodeList getElementsByName(DOMString elementName);
- NodeList getItems(optional DOMString typeNames = ""); // microdata
[SameObject] readonly attribute DOMElementMap cssElementMap;
readonly attribute HTMLScriptElement? currentScript;
@@ -132,15 +118,6 @@ interface HTMLElement : Element {
attribute DOMString dir;
[SameObject] readonly attribute DOMStringMap dataset;
- // microdata
- attribute boolean itemScope;
- [PutForwards=value] readonly attribute DOMSettableTokenList itemType;
- attribute DOMString itemId;
- [PutForwards=value] readonly attribute DOMSettableTokenList itemRef;
- [PutForwards=value] readonly attribute DOMSettableTokenList itemProp;
- readonly attribute HTMLPropertiesCollection properties;
- attribute any itemValue; // acts as DOMString on setting
-
// user interaction
attribute boolean hidden;
void click();
@@ -207,6 +184,7 @@ interface HTMLMetaElement : HTMLElement {
interface HTMLStyleElement : HTMLElement {
attribute DOMString media;
+ attribute DOMString nonce;
attribute DOMString type;
attribute boolean scoped;
};
@@ -267,7 +245,7 @@ interface HTMLDivElement : HTMLElement {
interface HTMLAnchorElement : HTMLElement {
attribute DOMString target;
attribute DOMString download;
- [PutForwards=value] attribute DOMSettableTokenList ping;
+ [PutForwards=value] readonly attribute DOMSettableTokenList ping;
attribute DOMString rel;
readonly attribute DOMTokenList relList;
attribute DOMString hreflang;
@@ -634,7 +612,6 @@ dictionary TrackEventInit : EventInit {
interface HTMLMapElement : HTMLElement {
attribute DOMString name;
readonly attribute HTMLCollection areas;
- readonly attribute HTMLCollection images;
};
interface HTMLAreaElement : HTMLElement {
@@ -643,7 +620,7 @@ interface HTMLAreaElement : HTMLElement {
attribute DOMString shape;
attribute DOMString target;
attribute DOMString download;
- [PutForwards=value] attribute DOMSettableTokenList ping;
+ [PutForwards=value] readonly attribute DOMSettableTokenList ping;
attribute DOMString rel;
readonly attribute DOMTokenList relList;
attribute DOMString hreflang;
@@ -861,7 +838,7 @@ interface HTMLSelectElement : HTMLElement {
void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or
long)? before = null);
void remove(); // ChildNode overload
void remove(long index);
- setter creator void (unsigned long index, HTMLOptionElement? option);
+ setter void (unsigned long index, HTMLOptionElement? option);
readonly attribute HTMLCollection selectedOptions;
attribute long selectedIndex;
@@ -1097,6 +1074,7 @@ interface HTMLScriptElement : HTMLElement {
attribute boolean defer;
attribute DOMString? crossOrigin;
attribute DOMString text;
+ attribute DOMString nonce;
// also has obsolete members
};
@@ -1139,6 +1117,8 @@ dictionary CanvasRenderingContext2DSettings {
boolean alpha = true;
};
+enum ImageSmoothingQuality { "low", "medium", "high" };
+
[Constructor(),
Constructor(unsigned long width, unsigned long height),
Exposed=(Window,Worker)]
@@ -1159,7 +1139,7 @@ interface CanvasRenderingContext2D {
void restore(); // pop state stack and restore state
// transformations (default transform is the identity matrix)
- attribute SVGMatrix currentTransform;
+ attribute DOMMatrix currentTransform;
void scale(unrestricted double x, unrestricted double y);
void rotate(unrestricted double angle);
void translate(unrestricted double x, unrestricted double y);
@@ -1173,6 +1153,7 @@ interface CanvasRenderingContext2D {
// image smoothing
attribute boolean imageSmoothingEnabled; // (default true)
+ attribute ImageSmoothingQuality imageSmoothingQuality; // (default low)
// colours and styles (see also the CanvasDrawingStyles interface)
attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default
black)
@@ -1279,7 +1260,7 @@ interface CanvasGradient {
[Exposed=(Window,Worker)]
interface CanvasPattern {
// opaque object
- void setTransform(SVGMatrix transform);
+ void setTransform(DOMMatrix transform);
};
[Exposed=(Window,Worker)]
@@ -1329,15 +1310,15 @@ DrawingStyle implements CanvasDrawingStyles;
[Constructor,
Constructor(Path2D path),
- Constructor(Path2D[] paths, optional CanvasFillRule fillRule = "nonzero"),
+ Constructor(sequence<Path2D> paths, optional CanvasFillRule fillRule =
"nonzero"),
Constructor(DOMString d), Exposed=(Window,Worker)]
interface Path2D {
- void addPath(Path2D path, optional SVGMatrix? transformation = null);
- void addPathByStrokingPath(Path2D path, CanvasDrawingStyles styles, optional SVGMatrix?
transformation = null);
- void addText(DOMString text, CanvasDrawingStyles styles, SVGMatrix? transformation,
unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
- void addPathByStrokingText(DOMString text, CanvasDrawingStyles styles, SVGMatrix?
transformation, unrestricted double x, unrestricted double y, optional unrestricted double
maxWidth);
- void addText(DOMString text, CanvasDrawingStyles styles, SVGMatrix? transformation,
Path2D path, optional unrestricted double maxWidth);
- void addPathByStrokingText(DOMString text, CanvasDrawingStyles styles, SVGMatrix?
transformation, Path2D path, optional unrestricted double maxWidth);
+ void addPath(Path2D path, optional DOMMatrix? transformation = null);
+ void addPathByStrokingPath(Path2D path, CanvasDrawingStyles styles, optional DOMMatrix?
transformation = null);
+ void addText(DOMString text, CanvasDrawingStyles styles, DOMMatrix? transformation,
unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
+ void addPathByStrokingText(DOMString text, CanvasDrawingStyles styles, DOMMatrix?
transformation, unrestricted double x, unrestricted double y, optional unrestricted double
maxWidth);
+ void addText(DOMString text, CanvasDrawingStyles styles, DOMMatrix? transformation,
Path2D path, optional unrestricted double maxWidth);
+ void addPathByStrokingText(DOMString text, CanvasDrawingStyles styles, DOMMatrix?
transformation, Path2D path, optional unrestricted double maxWidth);
};
Path2D implements CanvasPathMethods;
@@ -1399,7 +1380,7 @@ interface DragEvent : MouseEvent {
};
dictionary DragEventInit : MouseEventInit {
- DataTransfer? dataTransfer;
+ DataTransfer? dataTransfer = null;
};
[PrimaryGlobal]
@@ -1448,8 +1429,8 @@ dictionary DragEventInit : MouseEventInit {
void print();
any showModalDialog(DOMString url, optional any argument); // deprecated
- long requestAnimationFrame(FrameRequestCallback callback);
- void cancelAnimationFrame(long handle);
+ unsigned long requestAnimationFrame(FrameRequestCallback callback);
+ void cancelAnimationFrame(unsigned long handle);
void postMessage(any message, DOMString targetOrigin, optional
sequence<Transferable> transfer);
@@ -1458,14 +1439,16 @@ dictionary DragEventInit : MouseEventInit {
Window implements GlobalEventHandlers;
Window implements WindowEventHandlers;
+callback FrameRequestCallback = void (DOMHighResTimeStamp time);
+
interface BarProp {
- attribute boolean visible;
+ readonly attribute boolean visible;
};
interface History {
- readonly attribute long length;
+ readonly attribute unsigned long length;
readonly attribute any state;
- void go(optional long delta);
+ void go(optional long delta = 0);
void back();
void forward();
void pushState(any data, DOMString title, optional DOMString? url = null);
@@ -1620,7 +1603,7 @@ interface GlobalEventHandlers {
attribute EventHandler onmouseout;
attribute EventHandler onmouseover;
attribute EventHandler onmouseup;
- attribute EventHandler onmousewheel;
+ attribute EventHandler onwheel;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
@@ -1666,6 +1649,7 @@ interface WindowBase64 {
DOMString atob(DOMString atob);
};
Window implements WindowBase64;
+WorkerGlobalScope implements WindowBase64;
[NoInterfaceObject, Exposed=(Window,Worker)]
interface WindowTimers {
@@ -1677,6 +1661,7 @@ interface WindowTimers {
void clearInterval(optional long handle = 0);
};
Window implements WindowTimers;
+WorkerGlobalScope implements WindowTimers;
[NoInterfaceObject]
interface WindowModal {
@@ -1696,14 +1681,21 @@ Navigator implements NavigatorPlugins;
[NoInterfaceObject, Exposed=(Window,Worker)]
interface NavigatorID {
- readonly attribute DOMString appCodeName; // constant "Mozilla"
- readonly attribute DOMString appName;
+ [Exposed=Window] readonly attribute DOMString appCodeName; // constant
"Mozilla"
+ readonly attribute DOMString appName; // constant "Netscape"
readonly attribute DOMString appVersion;
readonly attribute DOMString platform;
- readonly attribute DOMString product; // constant "Gecko"
- boolean taintEnabled(); // constant false
+ [Exposed=Window] readonly attribute DOMString product; // constant "Gecko"
+ [Exposed=Window] readonly attribute DOMString productSub;
readonly attribute DOMString userAgent;
- readonly attribute DOMString vendorSub;
+ [Exposed=Window] readonly attribute DOMString vendor;
+ [Exposed=Window] readonly attribute DOMString vendorSub; // constant ""
+
+ // also has obsolete members
+};
+
+partial interface NavigatorID {
+ [Exposed=Window] boolean taintEnabled(); // constant false
};
[NoInterfaceObject, Exposed=(Window,Worker)]
@@ -1800,7 +1792,7 @@ interface MessageEvent : Event {
readonly attribute (WindowProxy or MessagePort)? source;
readonly attribute MessagePort[]? ports;
- void initMessageEvent(DOMString typeArg, boolean canBubbleArg, boolean cancelableArg,
any dataArg, DOMString originArg, DOMString lastEventIdArg, (WindowProxy or MessagePort)
sourceArg, sequence<MessagePort>? portsArg);
+ void initMessageEvent(DOMString type, boolean bubbles, boolean cancelable, any data,
DOMString origin, DOMString lastEventId, (WindowProxy or MessagePort)? source,
sequence<MessagePort>? ports);
};
dictionary MessageEventInit : EventInit {
@@ -1808,7 +1800,7 @@ dictionary MessageEventInit : EventInit {
DOMString origin;
DOMString lastEventId;
(WindowProxy or MessagePort)? source;
- sequence<MessagePort> ports;
+ sequence<MessagePort>? ports;
};
[Constructor(DOMString url, optional EventSourceInit eventSourceInitDict),
Exposed=(Window,Worker)]
@@ -1834,7 +1826,7 @@ dictionary EventSourceInit {
};
enum BinaryType { "blob", "arraybuffer" };
-[Constructor(DOMString url, optional (DOMString or DOMString[]) protocols),
Exposed=(Window,Worker)]
+[Constructor(DOMString url, optional (DOMString or sequence<DOMString>) protocols),
Exposed=(Window,Worker)]
interface WebSocket : EventTarget {
readonly attribute DOMString url;
@@ -1893,17 +1885,7 @@ interface MessagePort : EventTarget {
};
// MessagePort implements Transferable;
-[Constructor, Exposed=(Window,Worker)]
-interface PortCollection {
- void add(MessagePort port);
- void remove(MessagePort port);
- void clear();
- void iterate(PortCollectionCallback callback);
-};
-
-callback PortCollectionCallback = void (MessagePort port);
-
-[Constructor(DOMString channel), Exposed=(Window,Worker)]
+[Constructor(DOMString name), Exposed=(Window,Worker)]
interface BroadcastChannel : EventTarget {
readonly attribute DOMString name;
void postMessage(any message);
@@ -1915,14 +1897,14 @@ interface BroadcastChannel : EventTarget {
interface WorkerGlobalScope : EventTarget {
readonly attribute WorkerGlobalScope self;
readonly attribute WorkerLocation location;
+ readonly attribute WorkerNavigator navigator;
+ void importScripts(DOMString... urls);
void close();
attribute OnErrorEventHandler onerror;
attribute EventHandler onlanguagechange;
attribute EventHandler onoffline;
attribute EventHandler ononline;
-
- // also has additional members in a partial interface
};
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker]
@@ -1952,35 +1934,36 @@ interface Worker : EventTarget {
};
Worker implements AbstractWorker;
-[Constructor(DOMString scriptURL, optional DOMString name), Exposed=(Window,Worker)]
+[Constructor(DOMString scriptURL, optional DOMString name = ""),
Exposed=(Window,Worker)]
interface SharedWorker : EventTarget {
readonly attribute MessagePort port;
};
SharedWorker implements AbstractWorker;
[Exposed=Worker]
-partial interface WorkerGlobalScope { // not obsolete
- void importScripts(DOMString... urls);
- readonly attribute WorkerNavigator navigator;
-};
-WorkerGlobalScope implements WindowTimers;
-WorkerGlobalScope implements WindowBase64;
-
-[Exposed=Worker]
interface WorkerNavigator {};
WorkerNavigator implements NavigatorID;
WorkerNavigator implements NavigatorLanguage;
WorkerNavigator implements NavigatorOnLine;
[Exposed=Worker]
-interface WorkerLocation { };
-WorkerLocation implements URLUtilsReadOnly;
+interface WorkerLocation {
+ stringifier readonly attribute USVString href;
+ readonly attribute USVString origin;
+ readonly attribute USVString protocol;
+ readonly attribute USVString host;
+ readonly attribute USVString hostname;
+ readonly attribute USVString port;
+ readonly attribute USVString pathname;
+ readonly attribute USVString search;
+ readonly attribute USVString hash;
+};
interface Storage {
readonly attribute unsigned long length;
DOMString? key(unsigned long index);
getter DOMString? getItem(DOMString key);
- setter creator void setItem(DOMString key, DOMString value);
+ setter void setItem(DOMString key, DOMString value);
deleter void removeItem(DOMString key);
void clear();
};
diff --git a/javascript/duktape/Console.bnd b/javascript/duktape/Console.bnd
index cb96cec..734f003 100644
--- a/javascript/duktape/Console.bnd
+++ b/javascript/duktape/Console.bnd
@@ -10,7 +10,7 @@
*/
class Console {
- private "unsigned int" group;
+ private unsigned int group;
prologue %{
#include <nsutils/time.h>
@@ -38,7 +38,7 @@ write_log_entry(duk_context *ctx, unsigned int group, char logtype)
}
%};
-}
+};
init Console ()
%{
@@ -174,4 +174,4 @@ method Console::trace ()
duk_set_top(ctx, 1);
write_log_entry(ctx, priv->group, 'S');
return 0;
-%}
\ No newline at end of file
+%}
diff --git a/javascript/duktape/Document.bnd b/javascript/duktape/Document.bnd
index 6d11ea9..a51b38d 100644
--- a/javascript/duktape/Document.bnd
+++ b/javascript/duktape/Document.bnd
@@ -8,32 +8,83 @@
*
http://www.opensource.org/licenses/mit-license
*/
-class Document {
- prologue %{
+prologue Document()
+%{
#include "utils/corestrings.h"
-#include "render/html_internal.h"
#include "utils/libdom.h"
-%};
-}
+#include "utils/utils.h"
-init Document("struct dom_document *" document::node);
+#include "render/html_internal.h"
+#include "content/urldb.h"
+
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
+%}
+
+
+init Document(struct dom_document *document::node);
method Document::write()
%{
struct html_content *htmlc;
duk_size_t text_len;
- for (int i = 0; i < duk_get_top(ctx); ++i)
+ dom_exception err;
+ const char *text;
+
+ for (int i = 0; i < duk_get_top(ctx); ++i) {
duk_safe_to_string(ctx, i);
+ }
duk_concat(ctx, duk_get_top(ctx));
- const char *text = duk_safe_to_lstring(ctx, 0, &text_len);
+ text = duk_safe_to_lstring(ctx, 0, &text_len);
LOG("Writing %*s", (int)text_len, text);
+
+ err = dom_node_get_user_data(priv->parent.node,
+ corestring_dom___ns_key_html_content_data,
+ &htmlc);
+ if ((err != DOM_NO_ERR) || (htmlc == NULL)) {
+ LOG("error getting htmlc. parent node:%p htmlc:%p",
+ priv->parent.node, htmlc);
+ return 0;
+ } else if (htmlc->parser == NULL) {
+ LOG("error; no parser for htmlc: %p", htmlc);
+ return 0;
+ }
+
+ dom_hubbub_parser_insert_chunk(htmlc->parser,
+ (uint8_t *)text, text_len);
+
+ return 0;
+%}
+
+method Document::writeln()
+%{
+ const char nl[] = "\n";
+ struct html_content *htmlc;
+ duk_size_t text_len;
+ const char *text;
dom_exception err;
+
+ for (int i = 0; i < duk_get_top(ctx); ++i) {
+ duk_safe_to_string(ctx, i);
+ }
+ duk_concat(ctx, duk_get_top(ctx));
+ text = duk_safe_to_lstring(ctx, 0, &text_len);
+
+ LOG("Writeln %*s", (int)text_len, text);
err = dom_node_get_user_data(priv->parent.node,
corestring_dom___ns_key_html_content_data,
&htmlc);
- if (err == DOM_NO_ERR && htmlc->parser != NULL) {
- dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)text, text_len);
+ if ((err != DOM_NO_ERR) || (htmlc == NULL)) {
+ LOG("error getting htmlc. parent node:%p htmlc:%p",
+ priv->parent.node, htmlc);
+ return 0;
+ } else if (htmlc->parser == NULL) {
+ LOG("error; no parser for htmlc: %p", htmlc);
+ return 0;
}
+
+ dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)text, text_len);
+ dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)nl, SLEN(nl));
+
return 0;
%}
@@ -154,6 +205,19 @@ getter Document::body()
return 0; /* coerced to undefined */
%}
+getter Document::location()
+%{
+ /* retrieve the location object from the root object (window) */
+ duk_push_global_object(ctx);
+ duk_get_prop_string(ctx, -1, "location");
+ if (duk_is_undefined(ctx, -1)) {
+ duk_pop(ctx);
+ return 0;
+ }
+ return 1;
+%}
+
+
method Document::getElementById()
%{
dom_string *elementId_dom;
@@ -183,6 +247,28 @@ method Document::getElementById()
return 0;
%}
+getter Document::documentElement()
+%{
+ dom_exception exc;
+ dom_element *element;
+
+ exc = dom_document_get_document_element(((node_private_t *)priv)->node,
+ &element);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
+
+ if (element == NULL) {
+ return 0;
+ }
+
+ dukky_push_node(ctx, (dom_node *)element);
+ dom_node_unref(element);
+
+ return 1;
+
+%}
+
method Document::getElementsByTagName()
%{
dom_nodelist *nodes;
@@ -207,3 +293,153 @@ method Document::getElementsByTagName()
dom_nodelist_unref(nodes);
return 1;
%}
+
+getter Document::cookie()
+%{
+ char *cookie_str;
+ struct html_content *htmlc;
+ dom_exception err;
+
+ err = dom_node_get_user_data(priv->parent.node,
+ corestring_dom___ns_key_html_content_data,
+ &htmlc);
+ if ((err == DOM_NO_ERR) && (htmlc != NULL)) {
+ cookie_str = urldb_get_cookie(llcache_handle_get_url(htmlc->base.llcache), false);
+ if (cookie_str != NULL) {
+ duk_push_string(ctx, cookie_str);
+ free(cookie_str);
+ return 1;
+ }
+ } else {
+ LOG("error getting htmlc. parent node:%p htmlc:%p",
+ priv->parent.node, htmlc);
+ }
+ return 0;
+%}
+
+getter Document::onabort();
+setter Document::onabort();
+getter Document::onautocompleteerror();
+setter Document::onautocompleteerror();
+getter Document::onautocomplete();
+setter Document::onautocomplete();
+getter Document::onblur();
+setter Document::onblur();
+getter Document::oncancel();
+setter Document::oncancel();
+getter Document::oncanplaythrough();
+setter Document::oncanplaythrough();
+getter Document::oncanplay();
+setter Document::oncanplay();
+getter Document::onchange();
+setter Document::onchange();
+getter Document::onclick();
+setter Document::onclick();
+getter Document::onclose();
+setter Document::onclose();
+getter Document::oncontextmenu();
+setter Document::oncontextmenu();
+getter Document::oncuechange();
+setter Document::oncuechange();
+getter Document::ondblclick();
+setter Document::ondblclick();
+getter Document::ondragend();
+setter Document::ondragend();
+getter Document::ondragenter();
+setter Document::ondragenter();
+getter Document::ondragexit();
+setter Document::ondragexit();
+getter Document::ondragleave();
+setter Document::ondragleave();
+getter Document::ondragover();
+setter Document::ondragover();
+getter Document::ondragstart();
+setter Document::ondragstart();
+getter Document::ondrag();
+setter Document::ondrag();
+getter Document::ondrop();
+setter Document::ondrop();
+getter Document::ondurationchange();
+setter Document::ondurationchange();
+getter Document::onemptied();
+setter Document::onemptied();
+getter Document::onended();
+setter Document::onended();
+getter Document::onfocus();
+setter Document::onfocus();
+getter Document::oninput();
+setter Document::oninput();
+getter Document::oninvalid();
+setter Document::oninvalid();
+getter Document::onkeydown();
+setter Document::onkeydown();
+getter Document::onkeypress();
+setter Document::onkeypress();
+getter Document::onkeyup();
+setter Document::onkeyup();
+getter Document::onloadeddata();
+setter Document::onloadeddata();
+getter Document::onloadedmetadata();
+setter Document::onloadedmetadata();
+getter Document::onloadstart();
+setter Document::onloadstart();
+getter Document::onload();
+setter Document::onload();
+getter Document::onmousedown();
+setter Document::onmousedown();
+getter Document::onmouseenter();
+setter Document::onmouseenter();
+getter Document::onmouseleave();
+setter Document::onmouseleave();
+getter Document::onmousemove();
+setter Document::onmousemove();
+getter Document::onmouseout();
+setter Document::onmouseout();
+getter Document::onmouseover();
+setter Document::onmouseover();
+getter Document::onmouseup();
+setter Document::onmouseup();
+getter Document::onpause();
+setter Document::onpause();
+getter Document::onplaying();
+setter Document::onplaying();
+getter Document::onplay();
+setter Document::onplay();
+getter Document::onprogress();
+setter Document::onprogress();
+getter Document::onratechange();
+setter Document::onratechange();
+getter Document::onreadystatechange();
+setter Document::onreadystatechange();
+getter Document::onreset();
+setter Document::onreset();
+getter Document::onresize();
+setter Document::onresize();
+getter Document::onscroll();
+setter Document::onscroll();
+getter Document::onseeked();
+setter Document::onseeked();
+getter Document::onseeking();
+setter Document::onseeking();
+getter Document::onselect();
+setter Document::onselect();
+getter Document::onshow();
+setter Document::onshow();
+getter Document::onsort();
+setter Document::onsort();
+getter Document::onstalled();
+setter Document::onstalled();
+getter Document::onsubmit();
+setter Document::onsubmit();
+getter Document::onsuspend();
+setter Document::onsuspend();
+getter Document::ontimeupdate();
+setter Document::ontimeupdate();
+getter Document::ontoggle();
+setter Document::ontoggle();
+getter Document::onvolumechange();
+setter Document::onvolumechange();
+getter Document::onwaiting();
+setter Document::onwaiting();
+getter Document::onwheel();
+setter Document::onwheel();
diff --git a/javascript/duktape/Element.bnd b/javascript/duktape/Element.bnd
index 7607f84..d34e8c1 100644
--- a/javascript/duktape/Element.bnd
+++ b/javascript/duktape/Element.bnd
@@ -10,10 +10,11 @@
class Element {
prologue %{
+#include <utils/corestrings.h>
%};
-}
+};
-init Element("struct dom_element *" element::node);
+init Element(struct dom_element *element::node);
getter Element::firstElementChild()
%{
@@ -31,9 +32,7 @@ getter Element::firstElementChild()
exc = dom_node_get_node_type(element, &node_type);
if ((exc == DOM_NO_ERR) && (node_type == DOM_ELEMENT_NODE)) {
/* found it */
- dukky_push_node(ctx, (dom_node *)element);
- dom_node_unref(element);
- return 1;
+ break;
}
exc = dom_node_get_next_sibling(element, &next_node);
@@ -44,7 +43,12 @@ getter Element::firstElementChild()
element = NULL;
}
}
- return 0;
+ if (dukky_push_node(ctx, (dom_node *)element) == false) {
+ dom_node_unref(element);
+ return 0;
+ }
+ dom_node_unref(element);
+ return 1;
%}
getter Element::lastElementChild()
@@ -63,9 +67,7 @@ getter Element::lastElementChild()
exc = dom_node_get_node_type(element, &node_type);
if ((exc == DOM_NO_ERR) && (node_type == DOM_ELEMENT_NODE)) {
/* found it */
- dukky_push_node(ctx, (dom_node *)element);
- dom_node_unref(element);
- return 1;
+ break;
}
exc = dom_node_get_previous_sibling(element, &next_node);
@@ -76,7 +78,12 @@ getter Element::lastElementChild()
element = NULL;
}
}
- return 0;
+ if (dukky_push_node(ctx, (dom_node *)element) == false) {
+ dom_node_unref(element);
+ return 0;
+ }
+ dom_node_unref(element);
+ return 1;
%}
getter Element::previousElementSibling()
@@ -95,9 +102,7 @@ getter Element::previousElementSibling()
exc = dom_node_get_node_type(element, &node_type);
if ((exc == DOM_NO_ERR) && (node_type == DOM_ELEMENT_NODE)) {
/* found it */
- dukky_push_node(ctx, (dom_node *)element);
- dom_node_unref(element);
- return 1;
+ break;
}
exc = dom_node_get_previous_sibling(element, &sib_node);
@@ -108,7 +113,12 @@ getter Element::previousElementSibling()
element = NULL;
}
}
- return 0;
+ if (dukky_push_node(ctx, (dom_node *)element) == false) {
+ dom_node_unref(element);
+ return 0;
+ }
+ dom_node_unref(element);
+ return 1;
%}
getter Element::nextElementSibling()
@@ -127,9 +137,7 @@ getter Element::nextElementSibling()
exc = dom_node_get_node_type(element, &node_type);
if ((exc == DOM_NO_ERR) && (node_type == DOM_ELEMENT_NODE)) {
/* found it */
- dukky_push_node(ctx, (dom_node *)element);
- dom_node_unref(element);
- return 1;
+ break;
}
exc = dom_node_get_next_sibling(element, &sib_node);
@@ -140,7 +148,12 @@ getter Element::nextElementSibling()
element = NULL;
}
}
- return 0;
+ if (dukky_push_node(ctx, (dom_node *)element) == false) {
+ dom_node_unref(element);
+ return 0;
+ }
+ dom_node_unref(element);
+ return 1;
%}
getter Element::childElementCount()
@@ -197,3 +210,170 @@ method Element::getElementsByTagName ()
return 1;
%}
+
+getter Element::id ()
+%{
+ dom_string *idstr = NULL;
+ dom_exception exc;
+
+ exc = dom_element_get_attribute(priv->parent.node,
+ corestring_dom_id,
+ &idstr);
+ if (exc != DOM_NO_ERR) return 0;
+ if (idstr == NULL) {
+ duk_push_lstring(ctx, "", 0);
+ } else {
+ duk_push_lstring(ctx, dom_string_data(idstr),
+ dom_string_length(idstr));
+ dom_string_unref(idstr);
+ }
+ return 1;
+%}
+
+setter Element::id ()
+%{
+ dom_string *idstr = NULL;
+ dom_exception exc;
+ duk_size_t slen;
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create((const uint8_t *)s, slen, &idstr);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_element_set_attribute(priv->parent.node,
+ corestring_dom_id,
+ idstr);
+ dom_string_unref(idstr);
+ if (exc != DOM_NO_ERR) return 0;
+ return 0;
+%}
+
+
+method Element::removeAttribute()
+%{
+ dom_string *attr = NULL;
+ dom_exception exc;
+ duk_size_t slen;
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create((const uint8_t *)s, slen, &attr);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_element_remove_attribute(priv->parent.node, attr);
+ dom_string_unref(attr);
+ if (exc != DOM_NO_ERR) return 0;
+ return 0;
+%}
+
+method Element::getAttribute()
+%{
+ dom_string *attr_name = NULL;
+ dom_string *attr_value = NULL;
+ dom_exception exc;
+ duk_size_t slen;
+
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+ exc = dom_string_create((const uint8_t *)s, slen, &attr_name);
+ duk_pop(ctx);
+
+ exc = dom_element_get_attribute(priv->parent.node,
+ attr_name, &attr_value);
+ dom_string_unref(attr_name);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
+
+ if (attr_value == NULL) {
+ duk_push_null(ctx);
+ } else {
+ duk_push_lstring(ctx, dom_string_data(attr_value),
+ dom_string_length(attr_value));
+ dom_string_unref(attr_value);
+ }
+ return 1;
+%}
+
+method Element::setAttribute()
+%{
+ dom_exception exc;
+ dom_string *attr_str, *value_str;
+ duk_size_t attr_len, value_len;
+ const char *attr = duk_safe_to_lstring(ctx, 0, &attr_len);
+ const char *value = duk_safe_to_lstring(ctx, 1, &value_len);
+
+ exc = dom_string_create((const uint8_t *)attr, attr_len, &attr_str);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_string_create((const uint8_t *)value, value_len, &value_str);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(attr_str);
+ return 0;
+ }
+
+ exc = dom_element_set_attribute(priv->parent.node,
+ attr_str, value_str);
+ dom_string_unref(attr_str);
+ dom_string_unref(value_str);
+ if (exc != DOM_NO_ERR) return 0;
+ return 0;
+%}
+
+method Element::hasAttribute()
+%{
+ dom_string *attr_name = NULL;
+ dom_exception exc;
+ duk_size_t slen;
+ bool res;
+
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+ exc = dom_string_create((const uint8_t *)s, slen, &attr_name);
+ duk_pop(ctx);
+
+ exc = dom_element_has_attribute(priv->parent.node,
+ attr_name, &res);
+ dom_string_unref(attr_name);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
+
+ duk_push_boolean(ctx, res);
+ return 1;
+%}
+
+getter Element::className ()
+%{
+ dom_string *classstr = NULL;
+ dom_exception exc;
+
+ exc = dom_element_get_attribute(priv->parent.node,
+ corestring_dom_class,
+ &classstr);
+ if (exc != DOM_NO_ERR) return 0;
+ if (classstr == NULL) {
+ duk_push_lstring(ctx, "", 0);
+ } else {
+ duk_push_lstring(ctx, dom_string_data(classstr),
+ dom_string_length(classstr));
+ dom_string_unref(classstr);
+ }
+ return 1;
+%}
+
+setter Element::className ()
+%{
+ dom_string *classstr = NULL;
+ dom_exception exc;
+ duk_size_t slen;
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create((const uint8_t *)s, slen, &classstr);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_element_set_attribute(priv->parent.node,
+ corestring_dom_class,
+ classstr);
+ dom_string_unref(classstr);
+ if (exc != DOM_NO_ERR) return 0;
+ return 0;
+%}
+
diff --git a/javascript/duktape/Event.bnd b/javascript/duktape/Event.bnd
new file mode 100644
index 0000000..38e4640
--- /dev/null
+++ b/javascript/duktape/Event.bnd
@@ -0,0 +1,145 @@
+/* Event binding for browser using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ * Copyright 2015 Daniel Silverstone <dsilvers(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+class Event {
+ private dom_event *evt;
+};
+
+init Event (struct dom_event *evt)
+%{
+ priv->evt = evt;
+ dom_event_ref(evt);
+%}
+
+/* Note: many of these could be automatics once nsgenbind gets there. */
+
+getter Event::type ()
+%{
+ dom_string *ret;
+ dom_exception exc;
+
+ exc = dom_event_get_type(priv->evt, &ret);
+ if (exc != DOM_NO_ERR) return 0;
+ if (ret == NULL) {
+ duk_push_lstring(ctx, "", 0);
+ } else {
+ duk_push_lstring(ctx, dom_string_data(ret),
+ dom_string_length(ret));
+ dom_string_unref(ret);
+ }
+
+ return 1;
+%}
+
+getter Event::target ()
+%{
+ /** @todo Decide HTF this works wrt. Window as an event target */
+ dom_node *et;
+ dom_exception exc;
+
+ exc = dom_event_get_target(priv->evt, &et);
+ if (exc != DOM_NO_ERR) return 0;
+
+ dukky_push_node(ctx, et);
+ return 1;
+%}
+
+getter Event::currentTarget ()
+%{
+ /** @todo Decide HTF this works wrt. Window as an event target */
+ dom_node *et;
+ dom_exception exc;
+
+ exc = dom_event_get_current_target(priv->evt, &et);
+ if (exc != DOM_NO_ERR) return 0;
+
+ dukky_push_node(ctx, et);
+ return 1;
+%}
+
+getter Event::eventPhase ()
+%{
+ dom_exception exc;
+ dom_event_flow_phase phase;
+
+ exc = dom_event_get_event_phase(priv->evt, &phase);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_uint(ctx, phase);
+ return 1;
+%}
+
+method Event::stopPropagation ()
+%{
+ dom_exception exc;
+
+ exc = dom_event_stop_propagation(priv->evt);
+ if (exc != DOM_NO_ERR) return 0;
+
+ return 0;
+%}
+
+method Event::stopImmediatePropagation ()
+%{
+ dom_exception exc;
+
+ exc = dom_event_stop_immediate_propagation(priv->evt);
+ if (exc != DOM_NO_ERR) return 0;
+
+ return 0;
+%}
+
+getter Event::bubbles ()
+%{
+ dom_exception exc;
+ bool ret;
+
+ exc = dom_event_get_bubbles(priv->evt, &ret);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_boolean(ctx, ret);
+ return 1;
+%}
+
+getter Event::cancelable ()
+%{
+ dom_exception exc;
+ bool ret;
+
+ exc = dom_event_get_cancelable(priv->evt, &ret);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_boolean(ctx, ret);
+ return 1;
+%}
+
+method Event::preventDefault ()
+%{
+ dom_exception exc;
+
+ exc = dom_event_prevent_default(priv->evt);
+ if (exc != DOM_NO_ERR) return 0;
+
+ return 0;
+%}
+
+getter Event::defaultPrevented ()
+%{
+ dom_exception exc;
+ bool ret;
+
+ exc = dom_event_is_default_prevented(priv->evt, &ret);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_boolean(ctx, ret);
+ return 1;
+%}
+
diff --git a/javascript/duktape/HTMLAnchorElement.bnd
b/javascript/duktape/HTMLAnchorElement.bnd
new file mode 100644
index 0000000..3dcfef7
--- /dev/null
+++ b/javascript/duktape/HTMLAnchorElement.bnd
@@ -0,0 +1,39 @@
+/* HTML anchor element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLAnchorElement(struct dom_html_element *html_anchor_element::html_element);
+
+getter HTMLAnchorElement::charset();
+setter HTMLAnchorElement::charset();
+
+getter HTMLAnchorElement::coords();
+setter HTMLAnchorElement::coords();
+
+getter HTMLAnchorElement::hreflang();
+setter HTMLAnchorElement::hreflang();
+
+getter HTMLAnchorElement::name();
+setter HTMLAnchorElement::name();
+
+getter HTMLAnchorElement::rel();
+setter HTMLAnchorElement::rel();
+
+getter HTMLAnchorElement::rev();
+setter HTMLAnchorElement::rev();
+
+getter HTMLAnchorElement::shape();
+setter HTMLAnchorElement::shape();
+
+getter HTMLAnchorElement::target();
+setter HTMLAnchorElement::target();
+
+
+
+
diff --git a/javascript/duktape/HTMLAppletElement.bnd
b/javascript/duktape/HTMLAppletElement.bnd
new file mode 100644
index 0000000..8bf3ff2
--- /dev/null
+++ b/javascript/duktape/HTMLAppletElement.bnd
@@ -0,0 +1,30 @@
+/* HTML applet element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLAppletElement(struct dom_html_element *html_applet_element::html_element);
+
+getter HTMLAppletElement::align();
+setter HTMLAppletElement::align();
+getter HTMLAppletElement::alt();
+setter HTMLAppletElement::alt();
+getter HTMLAppletElement::archive();
+setter HTMLAppletElement::archive();
+getter HTMLAppletElement::codeBase();
+setter HTMLAppletElement::codeBase();
+getter HTMLAppletElement::code();
+setter HTMLAppletElement::code();
+getter HTMLAppletElement::height();
+setter HTMLAppletElement::height();
+getter HTMLAppletElement::name();
+setter HTMLAppletElement::name();
+getter HTMLAppletElement::object();
+setter HTMLAppletElement::object();
+getter HTMLAppletElement::width();
+setter HTMLAppletElement::width();
diff --git a/javascript/duktape/HTMLAreaElement.bnd
b/javascript/duktape/HTMLAreaElement.bnd
new file mode 100644
index 0000000..b6c1703
--- /dev/null
+++ b/javascript/duktape/HTMLAreaElement.bnd
@@ -0,0 +1,26 @@
+/* HTML area element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLAreaElement(struct dom_html_element *html_area_element::html_element);
+
+getter HTMLAreaElement::alt();
+setter HTMLAreaElement::alt();
+
+getter HTMLAreaElement::coords();
+setter HTMLAreaElement::coords();
+
+getter HTMLAreaElement::noHref();
+setter HTMLAreaElement::noHref();
+
+getter HTMLAreaElement::shape();
+setter HTMLAreaElement::shape();
+
+getter HTMLAreaElement::target();
+setter HTMLAreaElement::target();
diff --git a/javascript/duktape/HTMLBRElement.bnd b/javascript/duktape/HTMLBRElement.bnd
new file mode 100644
index 0000000..3b44b97
--- /dev/null
+++ b/javascript/duktape/HTMLBRElement.bnd
@@ -0,0 +1,14 @@
+/* HTML br element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLBRElement(struct dom_html_element *html_br_element::html_element);
+
+getter HTMLBRElement::clear();
+setter HTMLBRElement::clear();
diff --git a/javascript/duktape/HTMLBaseElement.bnd
b/javascript/duktape/HTMLBaseElement.bnd
new file mode 100644
index 0000000..143aefd
--- /dev/null
+++ b/javascript/duktape/HTMLBaseElement.bnd
@@ -0,0 +1,17 @@
+/* HTML base element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLBaseElement(struct dom_html_element *html_base_element::html_element);
+
+getter HTMLBaseElement::href();
+setter HTMLBaseElement::href();
+
+getter HTMLBaseElement::target();
+setter HTMLBaseElement::target();
diff --git a/javascript/duktape/HTMLBodyElement.bnd
b/javascript/duktape/HTMLBodyElement.bnd
new file mode 100644
index 0000000..a283f89
--- /dev/null
+++ b/javascript/duktape/HTMLBodyElement.bnd
@@ -0,0 +1,24 @@
+/* HTML body element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLBodyElement(struct dom_html_element *html_body_element::html_element);
+
+getter HTMLBodyElement::aLink();
+setter HTMLBodyElement::aLink();
+getter HTMLBodyElement::background();
+setter HTMLBodyElement::background();
+getter HTMLBodyElement::bgColor();
+setter HTMLBodyElement::bgColor();
+getter HTMLBodyElement::link();
+setter HTMLBodyElement::link();
+getter HTMLBodyElement::text();
+setter HTMLBodyElement::text();
+getter HTMLBodyElement::vLink();
+setter HTMLBodyElement::vLink();
diff --git a/javascript/duktape/HTMLButtonElement.bnd
b/javascript/duktape/HTMLButtonElement.bnd
new file mode 100644
index 0000000..53431aa
--- /dev/null
+++ b/javascript/duktape/HTMLButtonElement.bnd
@@ -0,0 +1,18 @@
+/* HTML button element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLButtonElement(struct dom_html_element *html_button_element::html_element);
+
+getter HTMLButtonElement::disabled();
+setter HTMLButtonElement::disabled();
+getter HTMLButtonElement::name();
+setter HTMLButtonElement::name();
+getter HTMLButtonElement::value();
+setter HTMLButtonElement::value();
diff --git a/javascript/duktape/HTMLCollection.bnd
b/javascript/duktape/HTMLCollection.bnd
index 08a162d..2ffe702 100644
--- a/javascript/duktape/HTMLCollection.bnd
+++ b/javascript/duktape/HTMLCollection.bnd
@@ -9,10 +9,10 @@
*/
class HTMLCollection {
- private "struct dom_html_collection *" coll;
-}
+ private struct dom_html_collection *coll;
+};
-init HTMLCollection("struct dom_html_collection *" coll)
+init HTMLCollection(struct dom_html_collection *coll)
%{
priv->coll = coll;
dom_html_collection_ref(coll);
diff --git a/javascript/duktape/HTMLDivElement.bnd
b/javascript/duktape/HTMLDivElement.bnd
new file mode 100644
index 0000000..759e34d
--- /dev/null
+++ b/javascript/duktape/HTMLDivElement.bnd
@@ -0,0 +1,14 @@
+/* HTML div element binding using duktape and libdom
+ *
+ * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLDivElement(struct dom_html_element *html_div_element::html_element);
+
+getter HTMLDivElement::align();
+setter HTMLDivElement::align();
diff --git a/javascript/duktape/HTMLElement.bnd b/javascript/duktape/HTMLElement.bnd
new file mode 100644
index 0000000..d2b913a
--- /dev/null
+++ b/javascript/duktape/HTMLElement.bnd
@@ -0,0 +1,153 @@
+/* HTML element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+prologue HTMLElement()
+%{
+#include <utils/corestrings.h>
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
+%}
+
+init HTMLElement(struct dom_html_element *html_element::element);
+
+getter HTMLElement::dir();
+setter HTMLElement::dir();
+
+getter HTMLElement::lang();
+setter HTMLElement::lang();
+
+getter HTMLElement::title();
+setter HTMLElement::title();
+
+getter HTMLElement::onchange();
+setter HTMLElement::onchange();
+
+setter HTMLElement::onclick();
+getter HTMLElement::onclick();
+
+getter HTMLElement::onabort();
+setter HTMLElement::onabort();
+getter HTMLElement::onautocompleteerror();
+setter HTMLElement::onautocompleteerror();
+getter HTMLElement::onautocomplete();
+setter HTMLElement::onautocomplete();
+getter HTMLElement::onblur();
+setter HTMLElement::onblur();
+getter HTMLElement::oncancel();
+setter HTMLElement::oncancel();
+getter HTMLElement::oncanplaythrough();
+setter HTMLElement::oncanplaythrough();
+getter HTMLElement::oncanplay();
+setter HTMLElement::oncanplay();
+getter HTMLElement::onclose();
+setter HTMLElement::onclose();
+getter HTMLElement::oncontextmenu();
+setter HTMLElement::oncontextmenu();
+getter HTMLElement::oncuechange();
+setter HTMLElement::oncuechange();
+getter HTMLElement::ondblclick();
+setter HTMLElement::ondblclick();
+getter HTMLElement::ondragend();
+setter HTMLElement::ondragend();
+getter HTMLElement::ondragenter();
+setter HTMLElement::ondragenter();
+getter HTMLElement::ondragexit();
+setter HTMLElement::ondragexit();
+getter HTMLElement::ondragleave();
+setter HTMLElement::ondragleave();
+getter HTMLElement::ondragover();
+setter HTMLElement::ondragover();
+getter HTMLElement::ondragstart();
+setter HTMLElement::ondragstart();
+getter HTMLElement::ondrag();
+setter HTMLElement::ondrag();
+getter HTMLElement::ondrop();
+setter HTMLElement::ondrop();
+getter HTMLElement::ondurationchange();
+setter HTMLElement::ondurationchange();
+getter HTMLElement::onemptied();
+setter HTMLElement::onemptied();
+getter HTMLElement::onended();
+setter HTMLElement::onended();
+getter HTMLElement::onfocus();
+setter HTMLElement::onfocus();
+getter HTMLElement::oninput();
+setter HTMLElement::oninput();
+getter HTMLElement::oninvalid();
+setter HTMLElement::oninvalid();
+getter HTMLElement::onkeydown();
+setter HTMLElement::onkeydown();
+getter HTMLElement::onkeypress();
+setter HTMLElement::onkeypress();
+getter HTMLElement::onkeyup();
+setter HTMLElement::onkeyup();
+getter HTMLElement::onloadeddata();
+setter HTMLElement::onloadeddata();
+getter HTMLElement::onloadedmetadata();
+setter HTMLElement::onloadedmetadata();
+getter HTMLElement::onloadstart();
+setter HTMLElement::onloadstart();
+getter HTMLElement::onload();
+setter HTMLElement::onload();
+getter HTMLElement::onmousedown();
+setter HTMLElement::onmousedown();
+getter HTMLElement::onmouseenter();
+setter HTMLElement::onmouseenter();
+getter HTMLElement::onmouseleave();
+setter HTMLElement::onmouseleave();
+getter HTMLElement::onmousemove();
+setter HTMLElement::onmousemove();
+getter HTMLElement::onmouseout();
+setter HTMLElement::onmouseout();
+getter HTMLElement::onmouseover();
+setter HTMLElement::onmouseover();
+getter HTMLElement::onmouseup();
+setter HTMLElement::onmouseup();
+getter HTMLElement::onpause();
+setter HTMLElement::onpause();
+getter HTMLElement::onplaying();
+setter HTMLElement::onplaying();
+getter HTMLElement::onplay();
+setter HTMLElement::onplay();
+getter HTMLElement::onprogress();
+setter HTMLElement::onprogress();
+getter HTMLElement::onratechange();
+setter HTMLElement::onratechange();
+getter HTMLElement::onreset();
+setter HTMLElement::onreset();
+getter HTMLElement::onresize();
+setter HTMLElement::onresize();
+getter HTMLElement::onscroll();
+setter HTMLElement::onscroll();
+getter HTMLElement::onseeked();
+setter HTMLElement::onseeked();
+getter HTMLElement::onseeking();
+setter HTMLElement::onseeking();
+getter HTMLElement::onselect();
+setter HTMLElement::onselect();
+getter HTMLElement::onshow();
+setter HTMLElement::onshow();
+getter HTMLElement::onsort();
+setter HTMLElement::onsort();
+getter HTMLElement::onstalled();
+setter HTMLElement::onstalled();
+getter HTMLElement::onsubmit();
+setter HTMLElement::onsubmit();
+getter HTMLElement::onsuspend();
+setter HTMLElement::onsuspend();
+getter HTMLElement::ontimeupdate();
+setter HTMLElement::ontimeupdate();
+getter HTMLElement::ontoggle();
+setter HTMLElement::ontoggle();
+getter HTMLElement::onvolumechange();
+setter HTMLElement::onvolumechange();
+getter HTMLElement::onwaiting();
+setter HTMLElement::onwaiting();
+getter HTMLElement::onwheel();
+setter HTMLElement::onwheel();
diff --git a/javascript/duktape/HTMLFontElement.bnd
b/javascript/duktape/HTMLFontElement.bnd
new file mode 100644
index 0000000..e648a72
--- /dev/null
+++ b/javascript/duktape/HTMLFontElement.bnd
@@ -0,0 +1,20 @@
+/* HTML font element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLFontElement(struct dom_html_element *html_font_element::html_element);
+
+getter HTMLFontElement::color();
+setter HTMLFontElement::color();
+
+getter HTMLFontElement::face();
+setter HTMLFontElement::face();
+
+getter HTMLFontElement::size();
+setter HTMLFontElement::size();
diff --git a/javascript/duktape/HTMLFormElement.bnd
b/javascript/duktape/HTMLFormElement.bnd
new file mode 100644
index 0000000..3906cf0
--- /dev/null
+++ b/javascript/duktape/HTMLFormElement.bnd
@@ -0,0 +1,26 @@
+/* HTML form element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLFormElement(struct dom_html_element *html_form_element::html_element);
+
+getter HTMLFormElement::acceptCharset();
+setter HTMLFormElement::acceptCharset();
+
+getter HTMLFormElement::action();
+setter HTMLFormElement::action();
+
+getter HTMLFormElement::enctype();
+setter HTMLFormElement::enctype();
+
+getter HTMLFormElement::method();
+setter HTMLFormElement::method();
+
+getter HTMLFormElement::target();
+setter HTMLFormElement::target();
diff --git a/javascript/duktape/HTMLFrameElement.bnd
b/javascript/duktape/HTMLFrameElement.bnd
new file mode 100644
index 0000000..ee5cfe3
--- /dev/null
+++ b/javascript/duktape/HTMLFrameElement.bnd
@@ -0,0 +1,35 @@
+/* HTML frame element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLFrameElement(struct dom_html_element *html_frame_element::html_element);
+
+getter HTMLFrameElement::frameBorder();
+setter HTMLFrameElement::frameBorder();
+
+getter HTMLFrameElement::longDesc();
+setter HTMLFrameElement::longDesc();
+
+getter HTMLFrameElement::marginHeight();
+setter HTMLFrameElement::marginHeight();
+
+getter HTMLFrameElement::marginWidth();
+setter HTMLFrameElement::marginWidth();
+
+getter HTMLFrameElement::name();
+setter HTMLFrameElement::name();
+
+getter HTMLFrameElement::noResize();
+setter HTMLFrameElement::noResize();
+
+getter HTMLFrameElement::scrolling();
+setter HTMLFrameElement::scrolling();
+
+getter HTMLFrameElement::src();
+setter HTMLFrameElement::src();
diff --git a/javascript/duktape/HTMLFrameSetElement.bnd
b/javascript/duktape/HTMLFrameSetElement.bnd
new file mode 100644
index 0000000..cc66e93
--- /dev/null
+++ b/javascript/duktape/HTMLFrameSetElement.bnd
@@ -0,0 +1,17 @@
+/* HTML frame set element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLFrameSetElement(struct dom_html_element *html_frame_set_element::html_element);
+
+getter HTMLFrameSetElement::cols();
+setter HTMLFrameSetElement::cols();
+
+getter HTMLFrameSetElement::rows();
+setter HTMLFrameSetElement::rows();
diff --git a/javascript/duktape/HTMLHRElement.bnd b/javascript/duktape/HTMLHRElement.bnd
new file mode 100644
index 0000000..421ec49
--- /dev/null
+++ b/javascript/duktape/HTMLHRElement.bnd
@@ -0,0 +1,24 @@
+/* HTML hr element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLHRElement(struct dom_html_element *html_hr_element::html_element);
+
+getter HTMLHRElement::noShade();
+setter HTMLHRElement::noShade();
+
+getter HTMLHRElement::align();
+setter HTMLHRElement::align();
+
+getter HTMLHRElement::size();
+setter HTMLHRElement::size();
+
+getter HTMLHRElement::width();
+setter HTMLHRElement::width();
+
diff --git a/javascript/duktape/HTMLHTMLElement.bnd
b/javascript/duktape/HTMLHTMLElement.bnd
new file mode 100644
index 0000000..01697d8
--- /dev/null
+++ b/javascript/duktape/HTMLHTMLElement.bnd
@@ -0,0 +1,14 @@
+/* HTML html element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLHtmlElement(struct dom_html_element *html_html_element::html_element);
+
+getter HTMLHtmlElement::version();
+setter HTMLHtmlElement::version();
diff --git a/javascript/duktape/HTMLHeadingElement.bnd
b/javascript/duktape/HTMLHeadingElement.bnd
new file mode 100644
index 0000000..be51223
--- /dev/null
+++ b/javascript/duktape/HTMLHeadingElement.bnd
@@ -0,0 +1,14 @@
+/* HTML heading element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLHeadingElement(struct dom_html_element *html_heading_element::html_element);
+
+getter HTMLHeadingElement::align();
+setter HTMLHeadingElement::align();
diff --git a/javascript/duktape/HTMLIFrameElement.bnd
b/javascript/duktape/HTMLIFrameElement.bnd
new file mode 100644
index 0000000..6435376
--- /dev/null
+++ b/javascript/duktape/HTMLIFrameElement.bnd
@@ -0,0 +1,41 @@
+/* HTML I frame element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLIFrameElement(struct dom_html_element *html_iframe_element::html_element);
+
+getter HTMLIFrameElement::align();
+setter HTMLIFrameElement::align();
+
+getter HTMLIFrameElement::frameBorder();
+setter HTMLIFrameElement::frameBorder();
+
+getter HTMLIFrameElement::height();
+setter HTMLIFrameElement::height();
+
+getter HTMLIFrameElement::longDesc();
+setter HTMLIFrameElement::longDesc();
+
+getter HTMLIFrameElement::marginHeight();
+setter HTMLIFrameElement::marginHeight();
+
+getter HTMLIFrameElement::marginWidth();
+setter HTMLIFrameElement::marginWidth();
+
+getter HTMLIFrameElement::name();
+setter HTMLIFrameElement::name();
+
+getter HTMLIFrameElement::scrolling();
+setter HTMLIFrameElement::scrolling();
+
+getter HTMLIFrameElement::src();
+setter HTMLIFrameElement::src();
+
+getter HTMLIFrameElement::width();
+setter HTMLIFrameElement::width();
diff --git a/javascript/duktape/HTMLImageElement.bnd
b/javascript/duktape/HTMLImageElement.bnd
new file mode 100644
index 0000000..96b35b6
--- /dev/null
+++ b/javascript/duktape/HTMLImageElement.bnd
@@ -0,0 +1,47 @@
+/* HTML image element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLImageElement(struct dom_html_element *html_image_element::html_element);
+
+getter HTMLImageElement::align();
+setter HTMLImageElement::align();
+
+getter HTMLImageElement::alt();
+setter HTMLImageElement::alt();
+
+getter HTMLImageElement::border();
+setter HTMLImageElement::border();
+
+getter HTMLImageElement::isMap();
+setter HTMLImageElement::isMap();
+
+getter HTMLImageElement::longDesc();
+setter HTMLImageElement::longDesc();
+
+getter HTMLImageElement::name();
+setter HTMLImageElement::name();
+
+getter HTMLImageElement::src();
+setter HTMLImageElement::src();
+
+getter HTMLImageElement::useMap();
+setter HTMLImageElement::useMap();
+
+getter HTMLImageElement::height();
+setter HTMLImageElement::height();
+
+getter HTMLImageElement::hspace();
+setter HTMLImageElement::hspace();
+
+getter HTMLImageElement::vspace();
+setter HTMLImageElement::vspace();
+
+getter HTMLImageElement::width();
+setter HTMLImageElement::width();
diff --git a/javascript/duktape/HTMLInputElement.bnd
b/javascript/duktape/HTMLInputElement.bnd
new file mode 100644
index 0000000..23645d0
--- /dev/null
+++ b/javascript/duktape/HTMLInputElement.bnd
@@ -0,0 +1,64 @@
+/* HTML input element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLInputElement(struct dom_html_element *html_input_element::html_element);
+
+getter HTMLInputElement::accept();
+setter HTMLInputElement::accept();
+
+getter HTMLInputElement::align();
+setter HTMLInputElement::align();
+
+getter HTMLInputElement::alt();
+setter HTMLInputElement::alt();
+
+getter HTMLInputElement::checked();
+setter HTMLInputElement::checked();
+
+getter HTMLInputElement::defaultChecked();
+setter HTMLInputElement::defaultChecked();
+
+getter HTMLInputElement::defaultValue();
+setter HTMLInputElement::defaultValue();
+
+getter HTMLInputElement::disabled();
+setter HTMLInputElement::disabled();
+
+getter HTMLInputElement::name();
+setter HTMLInputElement::name();
+
+getter HTMLInputElement::readOnly();
+setter HTMLInputElement::readOnly();
+
+getter HTMLInputElement::src();
+setter HTMLInputElement::src();
+
+getter HTMLInputElement::useMap();
+setter HTMLInputElement::useMap();
+
+getter HTMLInputElement::valueAsNumber();
+setter HTMLInputElement::valueAsNumber();
+
+getter HTMLInputElement::valueHigh();
+setter HTMLInputElement::valueHigh();
+
+getter HTMLInputElement::valueLow();
+setter HTMLInputElement::valueLow();
+
+getter HTMLInputElement::value();
+setter HTMLInputElement::value();
+
+getter HTMLInputElement::maxLength();
+setter HTMLInputElement::maxLength();
+
+getter HTMLInputElement::size();
+setter HTMLInputElement::size();
+
+getter HTMLInputElement::type();
diff --git a/javascript/duktape/HTMLLIElement.bnd b/javascript/duktape/HTMLLIElement.bnd
new file mode 100644
index 0000000..a585693
--- /dev/null
+++ b/javascript/duktape/HTMLLIElement.bnd
@@ -0,0 +1,17 @@
+/* HTML li element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLLIElement(struct dom_html_element *html_li_element::html_element);
+
+getter HTMLLIElement::type();
+setter HTMLLIElement::type();
+
+getter HTMLLIElement::value();
+setter HTMLLIElement::value();
diff --git a/javascript/duktape/HTMLLabelElement.bnd
b/javascript/duktape/HTMLLabelElement.bnd
new file mode 100644
index 0000000..018f798
--- /dev/null
+++ b/javascript/duktape/HTMLLabelElement.bnd
@@ -0,0 +1,14 @@
+/* HTML label element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLLabelElement(struct dom_html_element *html_label_element::html_element);
+
+getter HTMLLabelElement::htmlFor();
+setter HTMLLabelElement::htmlFor();
diff --git a/javascript/duktape/HTMLLegendElement.bnd
b/javascript/duktape/HTMLLegendElement.bnd
new file mode 100644
index 0000000..1bb95a9
--- /dev/null
+++ b/javascript/duktape/HTMLLegendElement.bnd
@@ -0,0 +1,14 @@
+/* HTML legend element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLLegendElement(struct dom_html_element *html_legend_element::html_element);
+
+getter HTMLLegendElement::align();
+setter HTMLLegendElement::align();
diff --git a/javascript/duktape/HTMLLinkElement.bnd
b/javascript/duktape/HTMLLinkElement.bnd
new file mode 100644
index 0000000..b215d76
--- /dev/null
+++ b/javascript/duktape/HTMLLinkElement.bnd
@@ -0,0 +1,35 @@
+/* HTML link element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLLinkElement(struct dom_html_element *html_link_element::html_element);
+
+getter HTMLLinkElement::charset();
+setter HTMLLinkElement::charset();
+
+getter HTMLLinkElement::hreflang();
+setter HTMLLinkElement::hreflang();
+
+getter HTMLLinkElement::href();
+setter HTMLLinkElement::href();
+
+getter HTMLLinkElement::media();
+setter HTMLLinkElement::media();
+
+getter HTMLLinkElement::rel();
+setter HTMLLinkElement::rel();
+
+getter HTMLLinkElement::rev();
+setter HTMLLinkElement::rev();
+
+getter HTMLLinkElement::target();
+setter HTMLLinkElement::target();
+
+getter HTMLLinkElement::type();
+setter HTMLLinkElement::type();
diff --git a/javascript/duktape/HTMLMapElement.bnd
b/javascript/duktape/HTMLMapElement.bnd
new file mode 100644
index 0000000..0603f6f
--- /dev/null
+++ b/javascript/duktape/HTMLMapElement.bnd
@@ -0,0 +1,14 @@
+/* HTML map element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLMapElement(struct dom_html_element *html_map_element::html_element);
+
+getter HTMLMapElement::name();
+setter HTMLMapElement::name();
diff --git a/javascript/duktape/HTMLMarqueeElement.bnd
b/javascript/duktape/HTMLMarqueeElement.bnd
new file mode 100644
index 0000000..16fbdc8
--- /dev/null
+++ b/javascript/duktape/HTMLMarqueeElement.bnd
@@ -0,0 +1,11 @@
+/* HTML marquee element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLMarqueeElement(struct dom_html_element *html_marquee_element::html_element);
diff --git a/javascript/duktape/HTMLMenuElement.bnd
b/javascript/duktape/HTMLMenuElement.bnd
new file mode 100644
index 0000000..c7097b7
--- /dev/null
+++ b/javascript/duktape/HTMLMenuElement.bnd
@@ -0,0 +1,14 @@
+/* HTML menu element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLMenuElement(struct dom_html_element *html_menu_element::html_element);
+
+getter HTMLMenuElement::compact();
+setter HTMLMenuElement::compact();
diff --git a/javascript/duktape/HTMLMetaElement.bnd
b/javascript/duktape/HTMLMetaElement.bnd
new file mode 100644
index 0000000..f9ecd4b
--- /dev/null
+++ b/javascript/duktape/HTMLMetaElement.bnd
@@ -0,0 +1,23 @@
+/* HTML meta element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLMetaElement(struct dom_html_element *html_meta_element::html_element);
+
+getter HTMLMetaElement::content();
+setter HTMLMetaElement::content();
+
+getter HTMLMetaElement::httpEquiv();
+setter HTMLMetaElement::httpEquiv();
+
+getter HTMLMetaElement::name();
+setter HTMLMetaElement::name();
+
+getter HTMLMetaElement::scheme();
+setter HTMLMetaElement::scheme();
diff --git a/javascript/duktape/HTMLOListElement.bnd
b/javascript/duktape/HTMLOListElement.bnd
new file mode 100644
index 0000000..8c12712
--- /dev/null
+++ b/javascript/duktape/HTMLOListElement.bnd
@@ -0,0 +1,18 @@
+/* HTML ol element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLOListElement(struct dom_html_element *html_o_list_element::html_element);
+
+getter HTMLOListElement::compact();
+setter HTMLOListElement::compact();
+getter HTMLOListElement::start();
+setter HTMLOListElement::start();
+getter HTMLOListElement::type();
+setter HTMLOListElement::type();
diff --git a/javascript/duktape/HTMLObjectElement.bnd
b/javascript/duktape/HTMLObjectElement.bnd
new file mode 100644
index 0000000..2d07a7b
--- /dev/null
+++ b/javascript/duktape/HTMLObjectElement.bnd
@@ -0,0 +1,54 @@
+/* HTML object element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLObjectElement(struct dom_html_element *html_object_element::html_element);
+
+getter HTMLObjectElement::align();
+setter HTMLObjectElement::align();
+
+getter HTMLObjectElement::archive();
+setter HTMLObjectElement::archive();
+
+getter HTMLObjectElement::border();
+setter HTMLObjectElement::border();
+
+getter HTMLObjectElement::codeBase();
+setter HTMLObjectElement::codeBase();
+
+getter HTMLObjectElement::code();
+setter HTMLObjectElement::code();
+
+getter HTMLObjectElement::codeType();
+setter HTMLObjectElement::codeType();
+
+getter HTMLObjectElement::data();
+setter HTMLObjectElement::data();
+
+getter HTMLObjectElement::declare();
+setter HTMLObjectElement::declare();
+
+getter HTMLObjectElement::height();
+setter HTMLObjectElement::height();
+
+getter HTMLObjectElement::name();
+setter HTMLObjectElement::name();
+
+getter HTMLObjectElement::standby();
+setter HTMLObjectElement::standby();
+
+getter HTMLObjectElement::type();
+setter HTMLObjectElement::type();
+
+getter HTMLObjectElement::useMap();
+setter HTMLObjectElement::useMap();
+
+getter HTMLObjectElement::width();
+setter HTMLObjectElement::width();
+
diff --git a/javascript/duktape/HTMLOptionElement.bnd
b/javascript/duktape/HTMLOptionElement.bnd
new file mode 100644
index 0000000..d5094b7
--- /dev/null
+++ b/javascript/duktape/HTMLOptionElement.bnd
@@ -0,0 +1,28 @@
+/* HTML option element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLOptionElement(struct dom_html_element *html_option_element::html_element);
+
+getter HTMLOptionElement::defaultSelected();
+setter HTMLOptionElement::defaultSelected();
+
+getter HTMLOptionElement::disabled();
+setter HTMLOptionElement::disabled();
+
+getter HTMLOptionElement::label();
+setter HTMLOptionElement::label();
+
+getter HTMLOptionElement::selected();
+setter HTMLOptionElement::selected();
+
+getter HTMLOptionElement::text();
+
+getter HTMLOptionElement::value();
+setter HTMLOptionElement::value();
diff --git a/javascript/duktape/HTMLParagraphElement.bnd
b/javascript/duktape/HTMLParagraphElement.bnd
new file mode 100644
index 0000000..cc9ad83
--- /dev/null
+++ b/javascript/duktape/HTMLParagraphElement.bnd
@@ -0,0 +1,14 @@
+/* HTML paragraph element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLParagraphElement(struct dom_html_element
*html_paragraph_element::html_element);
+
+getter HTMLParagraphElement::align();
+setter HTMLParagraphElement::align();
diff --git a/javascript/duktape/HTMLParamElement.bnd
b/javascript/duktape/HTMLParamElement.bnd
new file mode 100644
index 0000000..8fbe6fc
--- /dev/null
+++ b/javascript/duktape/HTMLParamElement.bnd
@@ -0,0 +1,23 @@
+/* HTML param element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLParamElement(struct dom_html_element *html_param_element::html_element);
+
+getter HTMLParamElement::name();
+setter HTMLParamElement::name();
+
+getter HTMLParamElement::type();
+setter HTMLParamElement::type();
+
+getter HTMLParamElement::value();
+setter HTMLParamElement::value();
+
+getter HTMLParamElement::valueType();
+setter HTMLParamElement::valueType();
diff --git a/javascript/duktape/HTMLPreElement.bnd
b/javascript/duktape/HTMLPreElement.bnd
new file mode 100644
index 0000000..06f6a76
--- /dev/null
+++ b/javascript/duktape/HTMLPreElement.bnd
@@ -0,0 +1,15 @@
+/* HTML li element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLPreElement(struct dom_html_element *html_pre_element::html_element);
+
+getter HTMLPreElement::width();
+setter HTMLPreElement::width();
+
diff --git a/javascript/duktape/HTMLQuoteElement.bnd
b/javascript/duktape/HTMLQuoteElement.bnd
new file mode 100644
index 0000000..9e62f5d
--- /dev/null
+++ b/javascript/duktape/HTMLQuoteElement.bnd
@@ -0,0 +1,14 @@
+/* HTML quote element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLQuoteElement(struct dom_html_element *html_quote_element::html_element);
+
+getter HTMLQuoteElement::cite();
+setter HTMLQuoteElement::cite();
diff --git a/javascript/duktape/HTMLScriptElement.bnd
b/javascript/duktape/HTMLScriptElement.bnd
new file mode 100644
index 0000000..b3b2266
--- /dev/null
+++ b/javascript/duktape/HTMLScriptElement.bnd
@@ -0,0 +1,32 @@
+/* HTML script element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLScriptElement(struct dom_html_element *html_script_element::html_element);
+
+getter HTMLScriptElement::charset();
+setter HTMLScriptElement::charset();
+
+getter HTMLScriptElement::defer();
+setter HTMLScriptElement::defer();
+
+getter HTMLScriptElement::event();
+setter HTMLScriptElement::event();
+
+getter HTMLScriptElement::htmlFor();
+setter HTMLScriptElement::htmlFor();
+
+getter HTMLScriptElement::src();
+setter HTMLScriptElement::src();
+
+getter HTMLScriptElement::text();
+setter HTMLScriptElement::text();
+
+getter HTMLScriptElement::type();
+setter HTMLScriptElement::type();
diff --git a/javascript/duktape/HTMLSelectElement.bnd
b/javascript/duktape/HTMLSelectElement.bnd
new file mode 100644
index 0000000..36a5d1d
--- /dev/null
+++ b/javascript/duktape/HTMLSelectElement.bnd
@@ -0,0 +1,26 @@
+/* HTML select element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLSelectElement(struct dom_html_element *html_select_element::html_element);
+
+getter HTMLSelectElement::disabled();
+setter HTMLSelectElement::disabled();
+
+getter HTMLSelectElement::multiple();
+setter HTMLSelectElement::multiple();
+
+getter HTMLSelectElement::name();
+setter HTMLSelectElement::name();
+
+getter HTMLSelectElement::type();
+
+getter HTMLSelectElement::value();
+setter HTMLSelectElement::value();
+
diff --git a/javascript/duktape/HTMLStyleElement.bnd
b/javascript/duktape/HTMLStyleElement.bnd
new file mode 100644
index 0000000..4510087
--- /dev/null
+++ b/javascript/duktape/HTMLStyleElement.bnd
@@ -0,0 +1,17 @@
+/* HTML style element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLStyleElement(struct dom_html_element *html_style_element::html_element);
+
+getter HTMLStyleElement::media();
+setter HTMLStyleElement::media();
+
+getter HTMLStyleElement::type();
+setter HTMLStyleElement::type();
diff --git a/javascript/duktape/HTMLTableCaptionElement.bnd
b/javascript/duktape/HTMLTableCaptionElement.bnd
new file mode 100644
index 0000000..75754cc
--- /dev/null
+++ b/javascript/duktape/HTMLTableCaptionElement.bnd
@@ -0,0 +1,14 @@
+/* HTML table caption element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableCaptionElement(struct dom_html_element
*html_table_caption_element::html_element);
+
+getter HTMLTableCaptionElement::align();
+setter HTMLTableCaptionElement::align();
diff --git a/javascript/duktape/HTMLTableCellElement.bnd
b/javascript/duktape/HTMLTableCellElement.bnd
new file mode 100644
index 0000000..7040344
--- /dev/null
+++ b/javascript/duktape/HTMLTableCellElement.bnd
@@ -0,0 +1,46 @@
+/* HTML table cell element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableCellElement(struct dom_html_element
*html_table_cell_element::html_element);
+
+getter HTMLTableCellElement::align();
+setter HTMLTableCellElement::align();
+
+getter HTMLTableCellElement::axis();
+setter HTMLTableCellElement::axis();
+
+getter HTMLTableCellElement::bgColor();
+setter HTMLTableCellElement::bgColor();
+
+getter HTMLTableCellElement::chOff();
+setter HTMLTableCellElement::chOff();
+
+getter HTMLTableCellElement::ch();
+setter HTMLTableCellElement::ch();
+
+getter HTMLTableCellElement::height();
+setter HTMLTableCellElement::height();
+
+getter HTMLTableCellElement::noWrap();
+setter HTMLTableCellElement::noWrap();
+
+getter HTMLTableCellElement::vAlign();
+setter HTMLTableCellElement::vAlign();
+
+getter HTMLTableCellElement::width();
+setter HTMLTableCellElement::width();
+
+getter HTMLTableCellElement::cellIndex();
+
+getter HTMLTableCellElement::colSpan();
+setter HTMLTableCellElement::colSpan();
+
+getter HTMLTableCellElement::rowSpan();
+setter HTMLTableCellElement::rowSpan();
diff --git a/javascript/duktape/HTMLTableColElement.bnd
b/javascript/duktape/HTMLTableColElement.bnd
new file mode 100644
index 0000000..ec7a954
--- /dev/null
+++ b/javascript/duktape/HTMLTableColElement.bnd
@@ -0,0 +1,26 @@
+/* HTML table col element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableColElement(struct dom_html_element *html_table_col_element::html_element);
+
+getter HTMLTableColElement::align();
+setter HTMLTableColElement::align();
+
+getter HTMLTableColElement::chOff();
+setter HTMLTableColElement::chOff();
+
+getter HTMLTableColElement::ch();
+setter HTMLTableColElement::ch();
+
+getter HTMLTableColElement::vAlign();
+setter HTMLTableColElement::vAlign();
+
+getter HTMLTableColElement::width();
+setter HTMLTableColElement::width();
diff --git a/javascript/duktape/HTMLTableElement.bnd
b/javascript/duktape/HTMLTableElement.bnd
new file mode 100644
index 0000000..cd6d357
--- /dev/null
+++ b/javascript/duktape/HTMLTableElement.bnd
@@ -0,0 +1,38 @@
+/* HTML table element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableElement(struct dom_html_element *html_table_element::html_element);
+
+getter HTMLTableElement::align();
+setter HTMLTableElement::align();
+
+getter HTMLTableElement::bgColor();
+setter HTMLTableElement::bgColor();
+
+getter HTMLTableElement::border();
+setter HTMLTableElement::border();
+
+getter HTMLTableElement::cellPadding();
+setter HTMLTableElement::cellPadding();
+
+getter HTMLTableElement::cellSpacing();
+setter HTMLTableElement::cellSpacing();
+
+getter HTMLTableElement::frame();
+setter HTMLTableElement::frame();
+
+getter HTMLTableElement::rules();
+setter HTMLTableElement::rules();
+
+getter HTMLTableElement::summary();
+setter HTMLTableElement::summary();
+
+getter HTMLTableElement::width();
+setter HTMLTableElement::width();
diff --git a/javascript/duktape/HTMLTableRowElement.bnd
b/javascript/duktape/HTMLTableRowElement.bnd
new file mode 100644
index 0000000..f736817
--- /dev/null
+++ b/javascript/duktape/HTMLTableRowElement.bnd
@@ -0,0 +1,30 @@
+/* HTML table row element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableRowElement(struct dom_html_element *html_table_row_element::html_element);
+
+getter HTMLTableRowElement::align();
+setter HTMLTableRowElement::align();
+
+getter HTMLTableRowElement::bgColor();
+setter HTMLTableRowElement::bgColor();
+
+getter HTMLTableRowElement::chOff();
+setter HTMLTableRowElement::chOff();
+
+getter HTMLTableRowElement::ch();
+setter HTMLTableRowElement::ch();
+
+getter HTMLTableRowElement::vAlign();
+setter HTMLTableRowElement::vAlign();
+
+getter HTMLTableRowElement::rowIndex();
+
+getter HTMLTableRowElement::sectionRowIndex();
diff --git a/javascript/duktape/HTMLTableSectionElement.bnd
b/javascript/duktape/HTMLTableSectionElement.bnd
new file mode 100644
index 0000000..276533b
--- /dev/null
+++ b/javascript/duktape/HTMLTableSectionElement.bnd
@@ -0,0 +1,23 @@
+/* HTML table section element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTableSectionElement(struct dom_html_element
*html_table_section_element::html_element);
+
+getter HTMLTableSectionElement::align();
+setter HTMLTableSectionElement::align();
+
+getter HTMLTableSectionElement::chOff();
+setter HTMLTableSectionElement::chOff();
+
+getter HTMLTableSectionElement::ch();
+setter HTMLTableSectionElement::ch();
+
+getter HTMLTableSectionElement::vAlign();
+setter HTMLTableSectionElement::vAlign();
diff --git a/javascript/duktape/HTMLTextAreaElement.bnd
b/javascript/duktape/HTMLTextAreaElement.bnd
new file mode 100644
index 0000000..a0fc1bf
--- /dev/null
+++ b/javascript/duktape/HTMLTextAreaElement.bnd
@@ -0,0 +1,30 @@
+/* HTML text area element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTextAreaElement(struct dom_html_element *html_text_area_element::html_element);
+
+getter HTMLTextAreaElement::defaultValue();
+setter HTMLTextAreaElement::defaultValue();
+
+getter HTMLTextAreaElement::disabled();
+setter HTMLTextAreaElement::disabled();
+
+getter HTMLTextAreaElement::name();
+setter HTMLTextAreaElement::name();
+
+getter HTMLTextAreaElement::readOnly();
+setter HTMLTextAreaElement::readOnly();
+
+getter HTMLTextAreaElement::type();
+
+getter HTMLTextAreaElement::value();
+setter HTMLTextAreaElement::value();
+
+
diff --git a/javascript/duktape/HTMLTitleElement.bnd
b/javascript/duktape/HTMLTitleElement.bnd
new file mode 100644
index 0000000..dee1c07
--- /dev/null
+++ b/javascript/duktape/HTMLTitleElement.bnd
@@ -0,0 +1,14 @@
+/* HTML title element binding using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+init HTMLTitleElement(struct dom_html_element *html_title_element::html_element);
+
+getter HTMLTitleElement::text();
+setter HTMLTitleElement::text();
diff --git a/javascript/duktape/Location.bnd b/javascript/duktape/Location.bnd
new file mode 100644
index 0000000..fbb0e4a
--- /dev/null
+++ b/javascript/duktape/Location.bnd
@@ -0,0 +1,353 @@
+/* Location binding for browser using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ * Copyright 2015 Daniel Silverstone <dsilvers(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+class Location {
+ private nsurl *url;
+};
+
+prologue Location()
+%{
+#include "desktop/browser.h"
+%}
+
+init Location(nsurl *url)
+%{
+ priv->url = url;
+ nsurl_ref(url);
+%}
+
+fini Location()
+%{
+ nsurl_unref(priv->url);
+%}
+
+method Location::reload()
+%{
+ /* retrieve the private data from the root object (window) */
+ 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);
+
+ if (priv_win->win != NULL) {
+ browser_window_reload(priv_win->win, false);
+ } else {
+ LOG("failed to get browser context");
+ }
+ return 0;
+%}
+
+method Location::assign()
+%{
+ /* retrieve the private data from the root object (window) */
+ 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);
+
+ if (priv_win == NULL || priv_win->win == NULL) {
+ LOG("failed to get browser context");
+ return 0;
+ }
+
+ nsurl *joined;
+ duk_size_t slen;
+ const char *url = duk_safe_to_lstring(ctx, 0, &slen);
+
+ nsurl_join(priv->url, url, &joined);
+ browser_window_navigate(priv_win->win,
+ joined,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(joined);
+ return 0;
+%}
+
+method Location::replace()
+%{
+ /* retrieve the private data from the root object (window) */
+ 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);
+
+ if (priv_win == NULL || priv_win->win == NULL) {
+ LOG("failed to get browser context");
+ return 0;
+ }
+
+ nsurl *joined;
+ duk_size_t slen;
+ const char *url = duk_safe_to_lstring(ctx, 0, &slen);
+
+ nsurl_join(priv->url, url, &joined);
+ browser_window_navigate(priv_win->win,
+ joined,
+ NULL,
+ BW_NAVIGATE_NONE,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(joined);
+ return 0;
+%}
+
+getter Location::href()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_COMPLETE, &url_s, &url_l);
+ if (url_s == NULL) {
+ return 0;
+ }
+
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+setter Location::href()
+%{
+ /* retrieve the private data from the root object (window) */
+ 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);
+
+ if (priv_win == NULL || priv_win->win == NULL) {
+ LOG("failed to get browser context");
+ return 0;
+ }
+
+ nsurl *joined;
+ duk_size_t slen;
+ const char *url = duk_safe_to_lstring(ctx, 0, &slen);
+
+ nsurl_join(priv->url, url, &joined);
+ browser_window_navigate(priv_win->win,
+ joined,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(joined);
+ return 0;
+%}
+
+getter Location::origin()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_SCHEME | NSURL_HOST | NSURL_PORT, &url_s,
&url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+getter Location::protocol()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_SCHEME, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::username()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_USERNAME, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::password()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_PASSWORD, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::host()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_HOST, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::hostname()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_HOST, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+
+getter Location::port()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_PORT, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::pathname()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_PATH, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::search()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_QUERY, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
+getter Location::hash()
+%{
+ char *url_s = NULL;
+ size_t url_l;
+
+ nsurl_get(priv->url, NSURL_FRAGMENT, &url_s, &url_l);
+
+ /* if url_s is NULL duk_push_lstring pushes an empty string
+ * which is correct for this API
+ */
+ duk_push_lstring(ctx, url_s, url_l);
+
+ if (url_s != NULL) {
+ free(url_s);
+ }
+
+ return 1;
+%}
+
+
diff --git a/javascript/duktape/Makefile b/javascript/duktape/Makefile
new file mode 100644
index 0000000..89353c3
--- /dev/null
+++ b/javascript/duktape/Makefile
@@ -0,0 +1,40 @@
+#
+# NetSurf javascript source file inclusion
+#
+# Included by javascript/Makefile
+#
+
+javascript/dukky.c: $(OBJROOT)/duktape/binding.h
+
+BINDINGS := $(wildcard javascript/duktape/*.bnd)
+
+# ensure genbind generates debugging files
+GBFLAGS+=-D
+
+$(OBJROOT)/duktape/binding.h $(OBJROOT)/duktape/Makefile: javascript/duktape/netsurf.bnd
$(BINDINGS)
+ $(Q)mkdir -p $(OBJROOT)/duktape
+ $(VQ)echo " GENBIND: $<"
+ $(Q)nsgenbind $(GBFLAGS) -I javascript/WebIDL $< $(OBJROOT)/duktape
+ $(VQ)echo " GENBIND: completed"
+
+# create unimplemented report for doxygen
+Docs/UnimplementedJavascript.txt: javascript/duktape/netsurf.bnd $(BINDINGS)
+ $(Q)mkdir -p $(OBJROOT)/duktape
+ $(VQ)echo "/** \page unimplemented Unimplemented javascript bindings" > $@
+ $(VQ)echo "This is a list of all the binding methods, getters and setters without
an implementation in a binding." >> $@
+ $(VQ)echo "" >> $@
+ $(VQ)echo " GENBIND: $<"
+ $(Q)nsgenbind $(GBFLAGS) -Wunimplemented -I javascript/WebIDL $< $(OBJROOT)/duktape
2>&1 >/dev/null | grep "Unimplemented" | cut -d' ' -f4- | sort
-k 2 | awk '{print $$0"\\n" }' >> $@
+ $(VQ)echo "*/" >> $@
+
+ifeq ($(filter $(MAKECMDGOALS),clean test coverage),)
+-include $(OBJROOT)/duktape/Makefile
+endif
+
+S_JAVASCRIPT_BINDING:=$(addprefix $(OBJROOT)/duktape/,$(NSGENBIND_SOURCES))
+
+$(S_JAVASCRIPT_BINDING): $(BINDINGS)
+
+S_JAVASCRIPT += content.c duktape/dukky.c duktape/duktape.c
+
+CFLAGS += -DDUK_OPT_HAVE_CUSTOM_H
diff --git a/javascript/duktape/Navigator.bnd b/javascript/duktape/Navigator.bnd
new file mode 100644
index 0000000..b18ca8e
--- /dev/null
+++ b/javascript/duktape/Navigator.bnd
@@ -0,0 +1,87 @@
+/* Navigator binding for browser using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ *
http://www.opensource.org/licenses/mit-license
+ */
+
+prologue Navigator()
+%{
+#include "utils/useragent.h"
+%}
+
+method Navigator::taintEnabled()
+%{
+ duk_push_boolean(ctx, false);
+ return 1;
+%}
+
+getter Navigator::appCodeName()
+%{
+ duk_push_string(ctx, "Mozilla");
+ return 1;
+%}
+
+getter Navigator::appName()
+%{
+ duk_push_string(ctx, "Netscape");
+ return 1;
+%}
+
+getter Navigator::appVersion()
+%{
+ duk_push_string(ctx, "3.4");
+ return 1;
+%}
+
+getter Navigator::platform()
+%{
+ duk_push_string(ctx, NULL);
+ return 1;
+%}
+
+getter Navigator::product()
+%{
+ duk_push_string(ctx, "Gecko");
+ return 1;
+%}
+
+getter Navigator::productSub()
+%{
+ duk_push_string(ctx, "20100101");
+ return 1;
+%}
+
+getter Navigator::vendor()
+%{
+ duk_push_string(ctx, NULL);
+ return 1;
+%}
+
+getter Navigator::vendorSub()
+%{
+ duk_push_string(ctx, NULL);
+ return 1;
+%}
+
+getter Navigator::cookieEnabled()
+%{
+ duk_push_boolean(ctx, false);
+ return 1;
+%}
+
+/* indicate there is no plugin for java installed */
+getter Navigator::javaEnabled()
+%{
+ duk_push_boolean(ctx, false);
+ return 1;
+%}
+
+getter Navigator::userAgent()
+%{
+ duk_push_string(ctx, user_agent_string());
+ return 1;
+%}
diff --git a/javascript/duktape/Node.bnd b/javascript/duktape/Node.bnd
index 2328710..a610afa 100644
--- a/javascript/duktape/Node.bnd
+++ b/javascript/duktape/Node.bnd
@@ -9,10 +9,10 @@
*/
class Node {
- private "dom_node *" node;
-}
+ private dom_node *node;
+};
-init Node("struct dom_node *" node)
+init Node(struct dom_node *node)
%{
priv->node = node;
dom_node_ref(node);
@@ -73,7 +73,6 @@ getter Node::parentNode()
dom_node *pnode = NULL;
exc = dom_node_get_parent_node(priv->node, &pnode);
if (exc != DOM_NO_ERR) return 0;
- if (pnode == NULL) return 0;
dukky_push_node(ctx, pnode);
dom_node_unref(pnode);
return 1;
@@ -83,15 +82,16 @@ getter Node::parentElement()
%{
dom_exception exc;
dom_node *pnode = NULL;
- dom_node_type ntype;
+ dom_node_type ntype = DOM_NODE_TYPE_COUNT + 1;
exc = dom_node_get_parent_node(priv->node, &pnode);
if (exc != DOM_NO_ERR) return 0;
- if (pnode == NULL) return 0;
- exc = dom_node_get_node_type(pnode, &ntype);
- if (exc != DOM_NO_ERR) { dom_node_unref(pnode); return 0; }
- dukky_push_node(ctx, pnode);
+ if (pnode != NULL) {
+ exc = dom_node_get_node_type(pnode, &ntype);
+ if (exc != DOM_NO_ERR) { dom_node_unref(pnode); return 0; }
+ }
+ dukky_push_node(ctx, (ntype == DOM_ELEMENT_NODE) ? pnode : NULL);
dom_node_unref(pnode);
- return (ntype == DOM_ELEMENT_NODE) ? 1 : 0;
+ return 1;
%}
method Node::hasChildNodes()
@@ -273,7 +273,7 @@ method Node::isEqualNode()
dom_exception exc;
bool result;
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
@@ -290,7 +290,7 @@ method Node::compareDocumentPosition()
dom_exception exc;
uint16_t ret;
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
@@ -311,7 +311,7 @@ method Node::contains()
dom_exception exc;
uint16_t ret;
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
@@ -386,7 +386,7 @@ method Node::isDefaultNamespace()
method Node::insertBefore()
%{
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
@@ -395,7 +395,7 @@ method Node::insertBefore()
dom_node *before = NULL;
if (duk_get_top(ctx) == 2) {
- if (!dukky_instanceof_at(ctx, 1, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 1, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 1, PRIVATE_MAGIC);
node_private_t *another = duk_get_pointer(ctx, -1);
before = another->node;
@@ -415,7 +415,7 @@ method Node::insertBefore()
method Node::appendChild()
%{
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
@@ -434,13 +434,13 @@ method Node::appendChild()
method Node::replaceChild()
%{
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
duk_pop(ctx);
- if (!dukky_instanceof_at(ctx, 1, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 1, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 1, PRIVATE_MAGIC);
node_private_t *old = duk_get_pointer(ctx, -1);
@@ -459,7 +459,7 @@ method Node::replaceChild()
method Node::removeChild()
%{
- if (!dukky_instanceof_at(ctx, 0, PROTO_NAME(NODE))) return 0;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(NODE))) return 0;
duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
node_private_t *other = duk_get_pointer(ctx, -1);
diff --git a/javascript/duktape/NodeList.bnd b/javascript/duktape/NodeList.bnd
index e085b6c..7ddf56d 100644
--- a/javascript/duktape/NodeList.bnd
+++ b/javascript/duktape/NodeList.bnd
@@ -9,10 +9,10 @@
*/
class NodeList {
- private "struct dom_nodelist *" nodes;
-}
+ private struct dom_nodelist *nodes;
+};
-init NodeList("struct dom_nodelist *" nodes)
+init NodeList(struct dom_nodelist *nodes)
%{
priv->nodes = nodes;
dom_nodelist_ref(nodes);
diff --git a/javascript/duktape/Window.bnd b/javascript/duktape/Window.bnd
index 1aacd5a..ed931c6 100644
--- a/javascript/duktape/Window.bnd
+++ b/javascript/duktape/Window.bnd
@@ -9,17 +9,17 @@
*/
class Window {
- private "struct browser_window *" win;
- private "struct html_content *" htmlc;
+ private struct browser_window * win;
+ private struct html_content * htmlc;
prologue %{
#include "utils/nsurl.h"
#include "desktop/browser.h"
#include "render/html.h"
#include "render/html_internal.h"
%};
-}
+};
-init Window("struct browser_window *" win, "struct html_content *"
htmlc)
+init Window(struct browser_window *win, struct html_content *htmlc)
%{
/* element window */
priv->win = win;
@@ -44,6 +44,9 @@ prototype Window()
EXPOSE(Date);
EXPOSE(RegExp);
EXPOSE(Math);
+ EXPOSE(Function);
+ EXPOSE(Proxy);
+ EXPOSE(String);
#undef EXPOSE
%}
@@ -76,3 +79,67 @@ getter Window::console()
}
return 1;
%}
+
+getter Window::location()
+%{
+ duk_push_this(ctx);
+ duk_get_prop_string(ctx, -1, MAGIC(Location));
+ if (duk_is_undefined(ctx, -1)) {
+ duk_pop(ctx);
+
+ duk_push_pointer(ctx, llcache_handle_get_url(priv->htmlc->base.llcache));
+
+ if (dukky_create_object(ctx, PROTO_NAME(LOCATION), 1) != DUK_EXEC_SUCCESS) {
+ duk_error(ctx, DUK_ERR_ERROR, "Unable to create location object");
+ return 0;
+ }
+ duk_dup(ctx, -1);
+ duk_put_prop_string(ctx, -3, MAGIC(Location));
+ }
+ return 1;
+%}
+
+getter Window::navigator()
+%{
+ duk_push_this(ctx);
+ duk_get_prop_string(ctx, -1, MAGIC(Navigator));
+ if (duk_is_undefined(ctx, -1)) {
+ duk_pop(ctx);
+
+ if (dukky_create_object(ctx,
+ PROTO_NAME(NAVIGATOR),
+ 0) != DUK_EXEC_SUCCESS) {
+ duk_error(ctx,
+ DUK_ERR_ERROR,
+ "Unable to create navigator object");
+ return 0;
+ }
+ duk_dup(ctx, -1);
+ duk_put_prop_string(ctx, -3, MAGIC(Navigator));
+ }
+ return 1;
+%}
+
+getter Window::name()
+%{
+ const char *name;
+ browser_window_get_name(priv->win, &name);
+ duk_push_string(ctx, name);
+ return 1;
+%}
+
+setter Window::name()
+%{
+ const char *name;
+ name = duk_to_string(ctx, -1);
+ browser_window_set_name(priv->win, name);
+ return 0;
+%}
+
+method Window::alert()
+%{
+ duk_size_t msg_len;
+ const char *msg = duk_safe_to_lstring(ctx, 0, &msg_len);
+ LOG("JS ALERT: %*s", (int)msg_len, msg);
+ return 0;
+%}
diff --git a/javascript/duktape/duk_config.h b/javascript/duktape/duk_config.h
index 2cdb49f..adf2754 100644
--- a/javascript/duktape/duk_config.h
+++ b/javascript/duktape/duk_config.h
@@ -170,6 +170,11 @@ static __inline__ unsigned long long duk_rdtsc(void) {
/* PowerPC */
#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__)
#define DUK_F_PPC
+#if defined(__PPC64__)
+#define DUK_F_PPC64
+#else
+#define DUK_F_PPC32
+#endif
#endif
/* Linux */
@@ -478,7 +483,9 @@ static __inline__ unsigned long long duk_rdtsc(void) {
* there is no platform specific date parsing/formatting but there is still
* the ISO 8601 standard format.
*/
+#if defined(DUK_COMPILING_DUKTAPE)
#include <windows.h>
+#endif
#include <limits.h>
#elif defined(DUK_F_FLASHPLAYER)
/* Crossbridge */
@@ -1082,6 +1089,11 @@ typedef duk_int_t duk_idx_t;
#define DUK_IDX_MIN DUK_INT_MIN
#define DUK_IDX_MAX DUK_INT_MAX
+/* Unsigned index variant. */
+typedef duk_uint_t duk_uidx_t;
+#define DUK_UIDX_MIN DUK_UINT_MIN
+#define DUK_UIDX_MAX DUK_UINT_MAX
+
/* Array index values, could be exact 32 bits.
* Currently no need for signed duk_arridx_t.
*/
@@ -1495,8 +1507,8 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_PACKED_TVAL_POSSIBLE
#endif
-/* PPC: packed always possible */
-#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_PPC)
+/* PPC32: packed always possible */
+#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_PPC32)
#define DUK_USE_PACKED_TVAL_POSSIBLE
#endif
@@ -2018,6 +2030,18 @@ typedef FILE duk_file;
#define DUK_ALWAYS_INLINE /*nop*/
#endif
+/* Temporary workaround for GH-323: avoid inlining control when
+ * compiling from multiple sources, as it causes compiler trouble.
+ */
+#if !defined(DUK_SINGLE_FILE)
+#undef DUK_NOINLINE
+#undef DUK_INLINE
+#undef DUK_ALWAYS_INLINE
+#define DUK_NOINLINE /*nop*/
+#define DUK_INLINE /*nop*/
+#define DUK_ALWAYS_INLINE /*nop*/
+#endif
+
/*
* Symbol visibility macros
*
@@ -2228,6 +2252,16 @@ typedef FILE duk_file;
#endif
/*
+ * Target info string
+ */
+
+#if defined(DUK_OPT_TARGET_INFO)
+#define DUK_USE_TARGET_INFO DUK_OPT_TARGET_INFO
+#else
+#define DUK_USE_TARGET_INFO "unknown"
+#endif
+
+/*
* Long control transfer, setjmp/longjmp or alternatives
*
* Signal mask is not saved (when that can be communicated to the platform)
@@ -2264,16 +2298,6 @@ typedef FILE duk_file;
#endif
/*
- * Target info string
- */
-
-#if defined(DUK_OPT_TARGET_INFO)
-#define DUK_USE_TARGET_INFO DUK_OPT_TARGET_INFO
-#else
-#define DUK_USE_TARGET_INFO "unknown"
-#endif
-
-/*
* Speed/size and other performance options
*/
@@ -2294,11 +2318,17 @@ typedef FILE duk_file;
* where a speed-size tradeoff exists (e.g. lookup tables). When it really
* matters, specific use flags may be appropriate.
*/
-#define DUK_USE_PREFER_SIZE
+#undef DUK_USE_PREFER_SIZE
/* Use a sliding window for lexer; slightly larger footprint, slightly faster. */
#define DUK_USE_LEXER_SLIDING_WINDOW
+/* Transparent JSON.stringify() fastpath. */
+#undef DUK_USE_JSON_STRINGIFY_FASTPATH
+#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH)
+#define DUK_USE_JSON_STRINGIFY_FASTPATH
+#endif
+
/*
* Tagged type representation (duk_tval)
*/
@@ -2447,6 +2477,16 @@ typedef FILE duk_file;
#define DUK_USE_DEBUGGER_DUMPHEAP
#endif
+#define DUK_USE_DEBUGGER_THROW_NOTIFY
+#if defined(DUK_OPT_NO_DEBUGGER_THROW_NOTIFY)
+#undef DUK_USE_DEBUGGER_THROW_NOTIFY
+#endif
+
+#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
+#if defined(DUK_OPT_DEBUGGER_PAUSE_UNCAUGHT)
+#define DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
+#endif
+
/* Debugger transport read/write torture. */
#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE
#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE)
@@ -2681,6 +2721,12 @@ typedef FILE duk_file;
#undef DUK_USE_NONSTD_ARRAY_WRITE
#endif
+/* Node.js Buffer and Khronos/ES6 typed array support. */
+#define DUK_USE_BUFFEROBJECT_SUPPORT
+#if defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT)
+#undef DUK_USE_BUFFEROBJECT_SUPPORT
+#endif
+
/*
* Optional C API options
*/
@@ -2704,20 +2750,6 @@ typedef FILE duk_file;
#endif
/*
- * Deep vs. shallow stack.
- *
- * Some embedded platforms have very shallow stack (e.g. 64kB); default to
- * a shallow stack on unknown platforms or known embedded platforms.
- */
-
-#if defined(DUK_F_LINUX) || defined(DUK_F_BSD) || defined(DUK_F_WINDOWS) || \
- defined(DUK_F_APPLE) || defined(DUK_OPT_DEEP_C_STACK)
-#define DUK_USE_DEEP_C_STACK
-#else
-#undef DUK_USE_DEEP_C_STACK
-#endif
-
-/*
* Ecmascript compiler
*/
@@ -2930,10 +2962,6 @@ typedef FILE duk_file;
#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS
#undef DUK_USE_EXPLICIT_NULL_INIT
-#if !defined(DUK_USE_PACKED_TVAL)
-#define DUK_USE_EXPLICIT_NULL_INIT
-#endif
-
#define DUK_USE_ZERO_BUFFER_DATA
#if defined(DUK_OPT_NO_ZERO_BUFFER_DATA)
#undef DUK_USE_ZERO_BUFFER_DATA
@@ -2988,6 +3016,42 @@ typedef FILE duk_file;
#endif
/*
+ * User declarations
+ */
+
+#if defined(DUK_OPT_DECLARE)
+#define DUK_USE_USER_DECLARE() DUK_OPT_DECLARE
+#else
+#define DUK_USE_USER_DECLARE() /* no user declarations */
+#endif
+
+/*
+ * Autogenerated defaults
+ */
+
+#define DUK_USE_COMPILER_RECLIMIT 2500
+#undef DUK_USE_DATE_FORMAT_STRING
+#undef DUK_USE_DATE_GET_LOCAL_TZOFFSET
+#undef DUK_USE_DATE_GET_NOW
+#undef DUK_USE_DATE_PARSE_STRING
+#undef DUK_USE_DATE_PRS_GETDATE
+#undef DUK_USE_EXEC_FUN_LOCAL
+#undef DUK_USE_INTEGER_ME
+#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
+#define DUK_USE_JSON_DECNUMBER_FASTPATH
+#define DUK_USE_JSON_DECSTRING_FASTPATH
+#define DUK_USE_JSON_DEC_RECLIMIT 1000
+#define DUK_USE_JSON_EATWHITE_FASTPATH
+#define DUK_USE_JSON_ENC_RECLIMIT 1000
+#define DUK_USE_JSON_QUOTESTRING_FASTPATH
+#undef DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE
+#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256
+#define DUK_USE_NATIVE_CALL_RECLIMIT 1000
+#undef DUK_USE_REFZERO_FINALIZER_TORTURE
+#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000
+#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000
+
+/*
* Alternative customization header
*
* If you want to modify the final DUK_USE_xxx flags directly (without
@@ -3000,6 +3064,14 @@ typedef FILE duk_file;
#endif
/*
+ * You may add overriding #define/#undef directives below for
+ * customization. You of course cannot un-#include or un-typedef
+ * anything; these require direct changes above.
+ */
+
+/* __OVERRIDE_DEFINES__ */
+
+/*
* Date provider selection
*
* User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll
@@ -3061,36 +3133,6 @@ DUK_INTERNAL_DECL duk_bool_t
duk_bi_date_format_parts_strftime(duk_context *ctx,
#endif /* DUK_COMPILING_DUKTAPE */
/*
- * User declarations
- */
-
-#if defined(DUK_OPT_DECLARE)
-#define DUK_USE_USER_DECLARE() DUK_OPT_DECLARE
-#else
-#define DUK_USE_USER_DECLARE() /* no user declarations */
-#endif
-
-/*
- * Autogenerated defaults
- */
-
-#undef DUK_USE_DATE_PRS_GETDATE
-#undef DUK_USE_INTEGER_ME
-#define DUK_USE_JSON_DECNUMBER_FASTPATH
-#define DUK_USE_JSON_DECSTRING_FASTPATH
-#define DUK_USE_JSON_EATWHITE_FASTPATH
-#define DUK_USE_JSON_QUOTESTRING_FASTPATH
-#undef DUK_USE_JSON_STRINGIFY_FASTPATH
-
-/*
- * You may add overriding #define/#undef directives below for
- * customization. You of course cannot un-#include or un-typedef
- * anything; these require direct changes above.
- */
-
-/* __OVERRIDE_DEFINES__ */
-
-/*
* Sanity check for the final effective internal defines. Also
* double checks user tweaks made by an optional duk_custom.h header.
*/
diff --git a/javascript/duktape/duk_custom.h b/javascript/duktape/duk_custom.h
index da9407f..625c6ba 100644
--- a/javascript/duktape/duk_custom.h
+++ b/javascript/duktape/duk_custom.h
@@ -27,3 +27,5 @@
#undef DUK_USE_DATE_PRS_GETDATE
#undef DUK_USE_DATE_PARSE_STRING
#endif
+
+#define DUK_USE_DEEP_C_STACK
diff --git a/javascript/dukky.c b/javascript/duktape/dukky.c
similarity index 52%
rename from javascript/dukky.c
rename to javascript/duktape/dukky.c
index 0358a57..b65e94b 100644
--- a/javascript/dukky.c
+++ b/javascript/duktape/dukky.c
@@ -32,41 +32,14 @@
#include "duktape/binding.h"
-#include "duktape/duktape.h"
+#include "duktape.h"
#include "dukky.h"
#include <dom/dom.h>
-
-duk_bool_t
-dukky_instanceof_at(duk_context *ctx, duk_idx_t _idx, const char *klass)
-{
- duk_idx_t idx = duk_normalize_index(ctx, _idx);
- /* ... ??? */
- if (!duk_check_type(ctx, idx, DUK_TYPE_OBJECT)) {
- return false;
- }
- /* ... obj */
- duk_get_global_string(ctx, "\xFF\xFFNETSURF_DUKTAPE_PROTOTYPES");
- /* ... obj protos */
- duk_get_prop_string(ctx, idx, klass);
- /* ... obj protos goalproto */
- duk_get_prototype(ctx, idx);
- /* ... obj protos goalproto proto? */
- while (!duk_is_undefined(ctx, -1)) {
- if (duk_strict_equals(ctx, -1, -2)) {
- duk_pop_3(ctx);
- return true;
- }
- duk_get_prototype(ctx, -1);
- /* ... obj protos goalproto proto proto? */
- duk_replace(ctx, -2);
- /* ... obj protos goalproto proto? */
- }
- duk_pop_3(ctx);
- /* ... obj */
- return false;
-}
+#define EVENT_MAGIC MAGIC(EVENT_MAP)
+#define HANDLER_LISTENER_MAGIC MAGIC(HANDLER_LISTENER_MAP)
+#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
static duk_ret_t dukky_populate_object(duk_context *ctx)
{
@@ -109,6 +82,14 @@ duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int
args)
/* ... args */
duk_push_object(ctx);
/* ... args obj */
+ duk_push_object(ctx);
+ /* ... args obj handlers */
+ duk_put_prop_string(ctx, -2, HANDLER_LISTENER_MAGIC);
+ /* ... args obj */
+ duk_push_object(ctx);
+ /* ... args obj handlers */
+ duk_put_prop_string(ctx, -2, HANDLER_MAGIC);
+ /* ... args obj */
duk_insert(ctx, -(args+1));
/* ... obj args */
duk_push_string(ctx, name);
@@ -141,6 +122,14 @@ dukky_push_node_stacked(duk_context *ctx)
/* ... nodeptr klass nodes */
duk_push_object(ctx);
/* ... nodeptr klass nodes obj */
+ duk_push_object(ctx);
+ /* ... nodeptr klass nodes obj handlers */
+ duk_put_prop_string(ctx, -2, HANDLER_LISTENER_MAGIC);
+ /* ... nodeptr klass nodes obj */
+ duk_push_object(ctx);
+ /* ... nodeptr klass nodes obj handlers */
+ duk_put_prop_string(ctx, -2, HANDLER_MAGIC);
+ /* ... nodeptr klass nodes obj */
duk_dup(ctx, -4);
/* ... nodeptr klass nodes obj nodeptr */
duk_dup(ctx, -4);
@@ -174,16 +163,16 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
{
dom_node_type nodetype;
dom_exception err;
-
+
err = dom_node_get_node_type(node, &nodetype);
if (err != DOM_NO_ERR) {
/* Oh bum, just node then */
duk_push_string(ctx, PROTO_NAME(NODE));
return;
}
-
+
switch(nodetype) {
- case DOM_ELEMENT_NODE: {
+ case DOM_ELEMENT_NODE: {
dom_string *namespace, *tag;
err = dom_node_get_namespace(node, &namespace);
if (err != DOM_NO_ERR) {
@@ -198,7 +187,7 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
duk_push_string(ctx, PROTO_NAME(ELEMENT));
break;
}
-
+
if (dom_string_isequal(namespace, corestring_dom_html_namespace) == false) {
/* definitely not an HTML element of some kind */
duk_push_string(ctx, PROTO_NAME(ELEMENT));
@@ -206,13 +195,13 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
break;
}
dom_string_unref(namespace);
-
+
err = dom_node_get_node_name(node, &tag);
if (err != DOM_NO_ERR) {
duk_push_string(ctx, PROTO_NAME(HTMLUNKNOWNELEMENT));
break;
}
-
+
duk_push_string(ctx, PROTO_NAME(HTML));
duk_push_lstring(ctx, dom_string_data(tag), dom_string_length(tag));
dom_string_unref(tag);
@@ -221,23 +210,23 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
break;
}
- case DOM_TEXT_NODE:
+ case DOM_TEXT_NODE:
duk_push_string(ctx, PROTO_NAME(TEXT));
break;
- case DOM_COMMENT_NODE:
+ case DOM_COMMENT_NODE:
duk_push_string(ctx, PROTO_NAME(COMMENT));
break;
- case DOM_DOCUMENT_NODE:
+ case DOM_DOCUMENT_NODE:
duk_push_string(ctx, PROTO_NAME(DOCUMENT));
break;
- case DOM_ATTRIBUTE_NODE:
- case DOM_PROCESSING_INSTRUCTION_NODE:
+ case DOM_ATTRIBUTE_NODE:
+ case DOM_PROCESSING_INSTRUCTION_NODE:
case DOM_DOCUMENT_TYPE_NODE:
- case DOM_DOCUMENT_FRAGMENT_NODE:
- case DOM_NOTATION_NODE:
+ case DOM_DOCUMENT_FRAGMENT_NODE:
+ case DOM_NOTATION_NODE:
case DOM_ENTITY_REFERENCE_NODE:
- case DOM_ENTITY_NODE:
- case DOM_CDATA_SECTION_NODE:
+ case DOM_ENTITY_NODE:
+ case DOM_CDATA_SECTION_NODE:
default:
/* Oh bum, just node then */
duk_push_string(ctx, PROTO_NAME(NODE));
@@ -373,11 +362,18 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void
*doc_priv)
duk_push_global_object(CTX);
duk_put_prop_string(CTX, -2, PROTO_MAGIC);
duk_set_global_object(CTX);
-
+
/* Now we need to prepare our node mapping table */
duk_push_object(CTX);
+ duk_push_pointer(CTX, NULL);
+ duk_push_null(CTX);
+ duk_put_prop(CTX, -3);
duk_put_global_string(CTX, NODE_MAGIC);
-
+
+ /* And now the event mapping table */
+ duk_push_object(CTX);
+ duk_put_global_string(CTX, EVENT_MAGIC);
+
return (jsobject *)ctx;
}
@@ -418,3 +414,312 @@ bool js_fire_event(jscontext *ctx, const char *type, struct
dom_document *doc, s
LOG("Oh dear, an event: %s", type);
return true;
}
+
+/*** New style event handling ***/
+
+static void dukky_push_event(duk_context *ctx, dom_event *evt)
+{
+ /* ... */
+ duk_get_global_string(ctx, EVENT_MAGIC);
+ /* ... events */
+ duk_push_pointer(ctx, evt);
+ /* ... events eventptr */
+ duk_get_prop(ctx, -2);
+ /* ... events event? */
+ if (duk_is_undefined(ctx, -1)) {
+ /* ... events undefined */
+ duk_pop(ctx);
+ /* ... events */
+ duk_push_pointer(ctx, evt);
+ if (dukky_create_object(ctx, PROTO_NAME(EVENT), 1) != DUK_EXEC_SUCCESS) {
+ /* ... events err */
+ duk_pop(ctx);
+ /* ... events */
+ duk_push_object(ctx);
+ /* ... events eobj[meh] */
+ }
+ /* ... events eobj */
+ duk_push_pointer(ctx, evt);
+ /* ... events eobj eventptr */
+ duk_dup(ctx, -2);
+ /* ... events eobj eventptr eobj */
+ duk_put_prop(ctx, -4);
+ /* ... events eobj */
+ }
+ /* ... events event */
+ duk_replace(ctx, -2);
+ /* ... event */
+}
+
+static void dukky_push_handler_code_(duk_context *ctx, dom_string *name,
+ dom_event_target *et)
+{
+ dom_string *onname, *val;
+ dom_element *ele = (dom_element *)et;
+ dom_exception exc;
+
+ exc = dom_string_concat(corestring_dom_on, name, &onname);
+ if (exc != DOM_NO_ERR) {
+ duk_push_lstring(ctx, "", 0);
+ return;
+ }
+
+ exc = dom_element_get_attribute(ele, onname, &val);
+ if ((exc != DOM_NO_ERR) || (val == NULL)) {
+ dom_string_unref(onname);
+ duk_push_lstring(ctx, "", 0);
+ return;
+ }
+
+ dom_string_unref(onname);
+ duk_push_lstring(ctx, dom_string_data(val), dom_string_length(val));
+ dom_string_unref(val);
+}
+
+bool dukky_get_current_value_of_event_handler(duk_context *ctx,
+ dom_string *name,
+ dom_event_target *et)
+{
+ /* Must be entered as:
+ * ... node(et)
+ */
+ duk_get_prop_string(ctx, -1, HANDLER_MAGIC);
+ /* ... node handlers */
+ duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name));
+ /* ... node handlers name */
+ duk_get_prop(ctx, -2);
+ /* ... node handlers handler? */
+ if (duk_is_undefined(ctx, -1)) {
+ /* ... node handlers undefined */
+ duk_pop_2(ctx);
+ /* ... node */
+ dukky_push_handler_code_(ctx, name, et);
+ /* ... node handlercode */
+ /** @todo This is entirely wrong, but it's hard to get right */
+ duk_push_string(ctx, "function (event) {");
+ /* ... node handlercode prefix */
+ duk_insert(ctx, -2);
+ /* ... node prefix handlercode */
+ duk_push_string(ctx, "}");
+ /* ... node prefix handlercode suffix */
+ duk_concat(ctx, 3);
+ /* ... node fullhandlersrc */
+ duk_push_string(ctx, "internal raw uncompiled handler");
+ /* ... node fullhandlersrc filename */
+ if (duk_pcompile(ctx, DUK_COMPILE_FUNCTION) != 0) {
+ /* ... node err */
+ LOG("Unable to proceed with handler, could not compile");
+ duk_pop_2(ctx);
+ return false;
+ }
+ /* ... node handler */
+ duk_insert(ctx, -2);
+ /* ... handler node */
+ } else {
+ /* ... node handlers handler */
+ duk_insert(ctx, -3);
+ /* ... handler node handlers */
+ duk_pop(ctx);
+ /* ... handler node */
+ }
+ /* ... handler node */
+ return true;
+}
+
+static void dukky_generic_event_handler(dom_event *evt, void *pw)
+{
+ duk_context *ctx = (duk_context *)pw;
+ dom_string *name;
+ dom_exception exc;
+ dom_event_target *targ;
+ dom_event_flow_phase phase;
+
+ LOG("WOOP WOOP, An event:");
+ exc = dom_event_get_type(evt, &name);
+ if (exc != DOM_NO_ERR) {
+ LOG("Unable to find the event name");
+ return;
+ }
+ LOG("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) {
+ LOG("Unable to get event phase");
+ return;
+ }
+ LOG("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);
+ LOG("Unable to find the event target");
+ return;
+ }
+
+ /* ... */
+ if (dukky_push_node(ctx, (dom_node *)targ) == false) {
+ dom_string_unref(name);
+ dom_node_unref(targ);
+ LOG("Unable to push JS node representation?!");
+ return;
+ }
+ /* ... node */
+ if (dukky_get_current_value_of_event_handler(
+ ctx, name, (dom_event_target *)targ) == false) {
+ dom_node_unref(targ);
+ dom_string_unref(name);
+ return;
+ }
+ /** @todo handle other kinds of event than the generic case */
+ dom_node_unref(targ);
+ dom_string_unref(name);
+ /* ... handler node */
+ dukky_push_event(ctx, evt);
+ /* ... handler node event */
+ if (duk_pcall_method(ctx, 1) != 0) {
+ /* Failed to run the method */
+ /* ... err */
+ LOG("OH NOES! An error running a callback. Meh.");
+ exc = dom_event_stop_immediate_propagation(evt);
+ if (exc != DOM_NO_ERR)
+ LOG("WORSE! could not stop propagation");
+ duk_get_prop_string(ctx, -1, "name");
+ duk_get_prop_string(ctx, -2, "message");
+ duk_get_prop_string(ctx, -3, "fileName");
+ duk_get_prop_string(ctx, -4, "lineNumber");
+ duk_get_prop_string(ctx, -5, "stack");
+ /* ... err name message fileName lineNumber stack */
+ LOG("Uncaught error in JS: %s: %s", duk_safe_to_string(ctx, -5),
+ duk_safe_to_string(ctx, -4));
+ LOG(" was at: %s line %s", duk_safe_to_string(ctx, -3),
+ duk_safe_to_string(ctx, -2));
+ LOG(" Stack trace: %s", duk_safe_to_string(ctx, -1));
+
+ duk_pop_n(ctx, 6);
+ /* ... */
+ return;
+ }
+ /* ... result */
+ if (duk_is_boolean(ctx, -1) &&
+ duk_to_boolean(ctx, -1) == 0) {
+ dom_event_prevent_default(evt);
+ }
+ duk_pop(ctx);
+ /* ... */
+}
+
+void dukky_register_event_listener_for(duk_context *ctx,
+ struct dom_element *ele,
+ dom_string *name)
+{
+ dom_event_listener *listen = NULL;
+ dom_exception exc;
+
+ /* ... */
+ if (dukky_push_node(ctx, (struct dom_node *)ele) == false)
+ return;
+ /* ... node */
+ duk_get_prop_string(ctx, -1, HANDLER_LISTENER_MAGIC);
+ /* ... node handlers */
+ duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name));
+ /* ... node handlers name */
+ if (duk_has_prop(ctx, -2)) {
+ /* ... node handlers */
+ duk_pop_2(ctx);
+ /* ... */
+ return;
+ }
+ /* ... node handlers */
+ duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name));
+ /* ... node handlers name */
+ duk_push_boolean(ctx, true);
+ /* ... node handlers name true */
+ duk_put_prop(ctx, -3);
+ /* ... node handlers */
+ duk_pop_2(ctx);
+ /* ... */
+ 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, false);
+ if (exc != DOM_NO_ERR) {
+ LOG("Unable to register listener for %p.%*s",
+ ele, dom_string_length(name), dom_string_data(name));
+ } else {
+ LOG("have registered listener for %p.%*s",
+ ele, dom_string_length(name), dom_string_data(name));
+ }
+ dom_event_listener_unref(listen);
+}
+
+
+void js_handle_new_element(jscontext *ctx, struct dom_element *node)
+{
+ assert(ctx);
+ assert(node);
+ dom_namednodemap *map;
+ dom_exception exc;
+ dom_ulong idx;
+ dom_ulong siz;
+ dom_attr *attr = NULL;
+ dom_string *key = NULL;
+
+ exc = dom_node_get_attributes(node, &map);
+ if (exc != DOM_NO_ERR) return;
+ if (map == NULL) return;
+
+ exc = dom_namednodemap_get_length(map, &siz);
+ if (exc != DOM_NO_ERR) goto out;
+
+ for (idx = 0; idx < siz; idx++) {
+ exc = dom_namednodemap_item(map, idx, &attr);
+ if (exc != DOM_NO_ERR) goto out;
+ exc = dom_attr_get_name(attr, &key);
+ if (exc != DOM_NO_ERR) goto out;
+ if (dom_string_length(key) > 2) {
+ /* Can be on* */
+ const uint8_t *data = (const uint8_t *)dom_string_data(key);
+ if (data[0] == 'o' && data[1] == 'n') {
+ dom_string *sub = NULL;
+ exc = dom_string_substr(
+ key, 2, dom_string_length(key),
+ &sub);
+ if (exc == DOM_NO_ERR) {
+ dukky_register_event_listener_for(
+ CTX, node, sub);
+ dom_string_unref(sub);
+ }
+ }
+ }
+ dom_string_unref(key); key = NULL;
+ dom_node_unref(attr); attr = NULL;
+ }
+
+out:
+ if (key != NULL)
+ dom_string_unref(key);
+
+ if (attr != NULL)
+ dom_node_unref(attr);
+
+ dom_namednodemap_unref(map);
+}
+
+void js_event_cleanup(jscontext *ctx, struct dom_event *evt)
+{
+ assert(ctx);
+ /* ... */
+ duk_get_global_string(CTX, EVENT_MAGIC);
+ /* ... EVENT_MAP */
+ duk_push_pointer(CTX, evt);
+ /* ... EVENT_MAP eventptr */
+ duk_del_prop(CTX, -2);
+ /* ... EVENT_MAP */
+ duk_pop(CTX);
+ /* ... */
+}
diff --git a/javascript/dukky.h b/javascript/duktape/dukky.h
similarity index 82%
rename from javascript/dukky.h
rename to javascript/duktape/dukky.h
index f484e3a..d1fff36 100644
--- a/javascript/dukky.h
+++ b/javascript/duktape/dukky.h
@@ -28,6 +28,11 @@ 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);
void dukky_inject_not_ctr(duk_context *ctx, int idx, const char *name);
-duk_bool_t dukky_instanceof_at(duk_context *ctx, duk_idx_t _idx, const char *klass);
+void dukky_register_event_listener_for(duk_context *ctx,
+ struct dom_element *ele,
+ dom_string *name);
+bool dukky_get_current_value_of_event_handler(duk_context *ctx,
+ dom_string *name,
+ dom_event_target *et);
#endif
diff --git a/javascript/duktape/duktape.c b/javascript/duktape/duktape.c
index d3133f5..530a27a 100644
--- a/javascript/duktape/duktape.c
+++ b/javascript/duktape/duktape.c
@@ -1,6 +1,10 @@
+// Omit from static analysis.
+#ifndef __clang_analyzer__
/*
- * Single file autogenerated distributable for Duktape 1.2.99.
- * Git commit 2a41d0a38eef5edfe8691cf09427b6ee8a3ad5c9 (v1.2.0-310-g2a41d0a).
+ * Single source autogenerated distributable for Duktape 1.3.99.
+
+ * Git commit 40453939c5a5aa16898d19bbac4d02f77196cc8b (v1.3.0-138-g4045393).
+ * Git branch regexp-canonicalize-lookup.
*
* See Duktape AUTHORS.rst and LICENSE.txt for copyright and
* licensing information.
@@ -53,8 +57,9 @@
* Please include an e-mail address, a link to your GitHub profile, or something
* similar to allow your contribution to be identified accurately.
*
-* The following people have contributed code and agreed to irrevocably license
-* their contributions under the Duktape ``LICENSE.txt`` (in order of appearance):
+* The following people have contributed code, website contents, or Wiki contents,
+* and agreed to irrevocably license their contributions under the Duktape
+* ``LICENSE.txt`` (in order of appearance):
*
* * Sami Vaarala <sami.vaarala(a)iki.fi>
* * Niki Dobrev
@@ -62,6 +67,7 @@
* * L\u00e1szl\u00f3 Lang\u00f3 <llango.u-szeged(a)partner.samsung.com>
* * Legimet <legimet.calc(a)gmail.com>
* * Karl Skomski <karl(a)skomski.com>
+* * Bruce Pascoe <fatcerberus1(a)gmail.com>
*
* Other contributions
* ===================
@@ -225,6 +231,7 @@ struct duk_hbufferobject;
struct duk_hbuffer;
struct duk_hbuffer_fixed;
struct duk_hbuffer_dynamic;
+struct duk_hbuffer_external;
struct duk_propaccessor;
union duk_propvalue;
@@ -275,6 +282,7 @@ typedef struct duk_hthread duk_hthread;
typedef struct duk_hbuffer duk_hbuffer;
typedef struct duk_hbuffer_fixed duk_hbuffer_fixed;
typedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;
+typedef struct duk_hbuffer_external duk_hbuffer_external;
typedef struct duk_propaccessor duk_propaccessor;
typedef union duk_propvalue duk_propvalue;
@@ -1581,13 +1589,13 @@ DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[2624];
DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[147];
DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[1952];
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[187];
+DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[1757];
#endif /* DUK_USE_BUILTIN_INITJS */
#endif /* !DUK_SINGLE_FILE */
#define DUK_BUILTINS_DATA_LENGTH 1952
#ifdef DUK_USE_BUILTIN_INITJS
-#define DUK_BUILTIN_INITJS_DATA_LENGTH 187
+#define DUK_BUILTIN_INITJS_DATA_LENGTH 1757
#endif /* DUK_USE_BUILTIN_INITJS */
#define DUK_BIDX_GLOBAL 0
@@ -2926,13 +2934,13 @@ DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[2624];
DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[147];
DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[1952];
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[187];
+DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[1757];
#endif /* DUK_USE_BUILTIN_INITJS */
#endif /* !DUK_SINGLE_FILE */
#define DUK_BUILTINS_DATA_LENGTH 1952
#ifdef DUK_USE_BUILTIN_INITJS
-#define DUK_BUILTIN_INITJS_DATA_LENGTH 187
+#define DUK_BUILTIN_INITJS_DATA_LENGTH 1757
#endif /* DUK_USE_BUILTIN_INITJS */
#define DUK_BIDX_GLOBAL 0
@@ -4271,13 +4279,13 @@ DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[2624];
DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[147];
DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[1952];
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[187];
+DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[1757];
#endif /* DUK_USE_BUILTIN_INITJS */
#endif /* !DUK_SINGLE_FILE */
#define DUK_BUILTINS_DATA_LENGTH 1952
#ifdef DUK_USE_BUILTIN_INITJS
-#define DUK_BUILTIN_INITJS_DATA_LENGTH 187
+#define DUK_BUILTIN_INITJS_DATA_LENGTH 1757
#endif /* DUK_USE_BUILTIN_INITJS */
#define DUK_BIDX_GLOBAL 0
@@ -4869,12 +4877,12 @@ DUK_INTERNAL_DECL duk_uint8_t
*duk_bw_insert_ensure_area(duk_hthread *thr, duk_b
DUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw,
duk_size_t off, duk_size_t len);
/* No duk_bw_remove_ensure_slice(), functionality would be identical. */
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t
**p);
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p,
duk_uint16_t val);
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p,
duk_uint32_t val);
-DUK_ALWAYS_INLINE DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p,
duk_double_t val);
+DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);
+DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);
+DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);
+DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);
+DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);
+DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);
#if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. */
DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);
@@ -4948,7 +4956,7 @@ DUK_INTERNAL_DECL const char *duk_str_not_configurable;
#define DUK_STR_SPRINTF_TOO_LONG duk_str_sprintf_too_long
#define DUK_STR_ALLOC_FAILED duk_str_alloc_failed
#define DUK_STR_POP_TOO_MANY duk_str_pop_too_many
-#define DUK_STR_BUFFER_NOT_DYNAMIC duk_str_buffer_not_dynamic
+#define DUK_STR_WRONG_BUFFER_TYPE duk_str_wrong_buffer_type
#define DUK_STR_FAILED_TO_EXTEND_VALSTACK duk_str_failed_to_extend_valstack
#define DUK_STR_ENCODE_FAILED duk_str_encode_failed
#define DUK_STR_DECODE_FAILED duk_str_decode_failed
@@ -4982,7 +4990,7 @@ DUK_INTERNAL_DECL const char *duk_str_buffer_too_long;
DUK_INTERNAL_DECL const char *duk_str_sprintf_too_long;
DUK_INTERNAL_DECL const char *duk_str_alloc_failed;
DUK_INTERNAL_DECL const char *duk_str_pop_too_many;
-DUK_INTERNAL_DECL const char *duk_str_buffer_not_dynamic;
+DUK_INTERNAL_DECL const char *duk_str_wrong_buffer_type;
DUK_INTERNAL_DECL const char *duk_str_failed_to_extend_valstack;
DUK_INTERNAL_DECL const char *duk_str_encode_failed;
DUK_INTERNAL_DECL const char *duk_str_decode_failed;
@@ -5344,11 +5352,6 @@ typedef duk_uint32_t duk_instr_t;
#define DUK_EXTRAOP_LABEL 32
#define DUK_EXTRAOP_ENDLABEL 33
-/* DUK_OP_EXTRA for debugging */
-#define DUK_EXTRAOP_DUMPREG 128
-#define DUK_EXTRAOP_DUMPREGS 129
-#define DUK_EXTRAOP_LOGMARK 130
-
/* DUK_OP_CALL flags in A */
#define DUK_BC_CALL_FLAG_TAILCALL (1 << 0)
#define DUK_BC_CALL_FLAG_EVALCALL (1 << 1)
@@ -5360,8 +5363,7 @@ typedef duk_uint32_t duk_instr_t;
#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING (1 << 3)
/* DUK_OP_RETURN flags in A */
-#define DUK_BC_RETURN_FLAG_FAST (1 << 0)
-#define DUK_BC_RETURN_FLAG_HAVE_RETVAL (1 << 1)
+#define DUK_BC_RETURN_FLAG_HAVE_RETVAL (1 << 0)
/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags
(DUK_PROPDESC_FLAG_XXX) */
#define DUK_BC_DECLVAR_FLAG_UNDEF_VALUE (1 << 4) /* use 'undefined'
for value automatically */
@@ -5818,11 +5820,6 @@ DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx
*lex_ctx, duk_re_
#define DUK_JS_COMPILER_H_INCLUDED
/* ecmascript compiler limits */
-#if defined(DUK_USE_DEEP_C_STACK)
-#define DUK_COMPILER_RECURSION_LIMIT 2500L
-#else
-#define DUK_COMPILER_RECURSION_LIMIT 50L
-#endif
#define DUK_COMPILER_TOKEN_LIMIT 100000000L /* 1e8: protects against deeply
nested inner functions */
/* maximum loopcount for peephole optimization */
@@ -5992,7 +5989,7 @@ struct duk_compiler_func {
duk_bool_t is_setget; /* is a setter/getter */
duk_bool_t is_decl; /* is a function declaration (as opposed to function
expression) */
duk_bool_t is_strict; /* function is strict */
- duk_bool_t is_notail; /* function must not be tailcalled */
+ duk_bool_t is_notail; /* function must not be tail called */
duk_bool_t in_directive_prologue; /* parsing in "directive prologue",
recognize directives */
duk_bool_t in_scanning; /* parsing in "scanning" phase (first
pass) */
duk_bool_t may_direct_eval; /* function may call direct eval */
@@ -6035,7 +6032,7 @@ struct duk_compiler_ctx {
* Prototypes
*/
-#define DUK_JS_COMPILE_FLAG_EVAL (1 << 0) /* source is eval code (not
program) */
+#define DUK_JS_COMPILE_FLAG_EVAL (1 << 0) /* source is eval code (not global)
*/
#define DUK_JS_COMPILE_FLAG_STRICT (1 << 1) /* strict outer context */
#define DUK_JS_COMPILE_FLAG_FUNCEXPR (1 << 2) /* source is a function expression
(used for Function constructor) */
@@ -6054,19 +6051,9 @@ DUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const
duk_uint8_t *src_b
#define DUK_RE_MAX_ATOM_COPIES 1000
/* regexp compilation limits */
-#if defined(DUK_USE_DEEP_C_STACK)
-#define DUK_RE_COMPILE_RECURSION_LIMIT 10000
-#else
-#define DUK_RE_COMPILE_RECURSION_LIMIT 100
-#endif
#define DUK_RE_COMPILE_TOKEN_LIMIT 100000000L /* 1e8 */
/* regexp execution limits */
-#if defined(DUK_USE_DEEP_C_STACK)
-#define DUK_RE_EXECUTE_RECURSION_LIMIT 10000
-#else
-#define DUK_RE_EXECUTE_RECURSION_LIMIT 100
-#endif
#define DUK_RE_EXECUTE_STEPS_LIMIT 1000000000L /* 1e9 */
/* regexp opcodes */
@@ -6149,7 +6136,7 @@ DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread
*thr); /* hack
*
* Selecting the tagged type format involves many trade-offs (memory
* use, size and performance of generated code, portability, etc),
- * see doc/types.txt for a detailed discussion (especially of how the
+ * see doc/types.rst for a detailed discussion (especially of how the
* IEEE double format is used to pack tagged values).
*
* NB: because macro arguments are often expressions, macros should
@@ -6185,22 +6172,20 @@ typedef union duk_double_union duk_tval;
#if defined(DUK_USE_FASTINT)
#define DUK_TAG_FASTINT 0xfff1UL /* embed: integer value */
#endif
-#define DUK_TAG_UNDEFINED 0xfff2UL /* embed: 0 or 1 (normal or unused) */
-#define DUK_TAG_NULL 0xfff3UL /* embed: nothing */
-#define DUK_TAG_BOOLEAN 0xfff4UL /* embed: 0 or 1 (false or true) */
+#define DUK_TAG_UNUSED 0xfff2UL /* marker; not actual tagged value */
+#define DUK_TAG_UNDEFINED 0xfff3UL /* embed: nothing */
+#define DUK_TAG_NULL 0xfff4UL /* embed: nothing */
+#define DUK_TAG_BOOLEAN 0xfff5UL /* embed: 0 or 1 (false or true) */
/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */
-#define DUK_TAG_POINTER 0xfff5UL /* embed: void ptr */
-#define DUK_TAG_LIGHTFUNC 0xfff6UL /* embed: func ptr */
-#define DUK_TAG_STRING 0xfff7UL /* embed: duk_hstring ptr */
-#define DUK_TAG_OBJECT 0xfff8UL /* embed: duk_hobject ptr */
-#define DUK_TAG_BUFFER 0xfff9UL /* embed: duk_hbuffer ptr */
+#define DUK_TAG_POINTER 0xfff6UL /* embed: void ptr */
+#define DUK_TAG_LIGHTFUNC 0xfff7UL /* embed: func ptr */
+#define DUK_TAG_STRING 0xfff8UL /* embed: duk_hstring ptr */
+#define DUK_TAG_OBJECT 0xfff9UL /* embed: duk_hobject ptr */
+#define DUK_TAG_BUFFER 0xfffaUL /* embed: duk_hbuffer ptr */
/* for convenience */
-#define DUK_XTAG_UNDEFINED_ACTUAL 0xfff20000UL
-#define DUK_XTAG_UNDEFINED_UNUSED 0xfff20001UL
-#define DUK_XTAG_NULL 0xfff30000UL
-#define DUK_XTAG_BOOLEAN_FALSE 0xfff40000UL
-#define DUK_XTAG_BOOLEAN_TRUE 0xfff40001UL
+#define DUK_XTAG_BOOLEAN_FALSE 0xfff50000UL
+#define DUK_XTAG_BOOLEAN_TRUE 0xfff50001UL
/* two casts to avoid gcc warning: "warning: cast from pointer to integer of
different size [-Wpointer-to-int-cast]" */
#ifdef DUK_USE_64BIT_OPS
@@ -6277,10 +6262,12 @@ typedef union duk_double_union duk_tval;
#define DUK__TVAL_GET_FASTINT_I32(v) ((duk_int32_t) (v)->ui[DUK_DBL_IDX_UI1])
#endif /* DUK_USE_FASTINT */
-#define DUK_TVAL_SET_UNDEFINED_ACTUAL(v) DUK_DBLUNION_SET_HIGH32((v),
DUK_XTAG_UNDEFINED_ACTUAL)
-#define DUK_TVAL_SET_UNDEFINED_UNUSED(v) DUK_DBLUNION_SET_HIGH32((v),
DUK_XTAG_UNDEFINED_UNUSED)
-
-/* Note: 16-bit initializer suffices (unlike for undefined/boolean) */
+#define DUK_TVAL_SET_UNDEFINED(v) do { \
+ (v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \
+ } while (0)
+#define DUK_TVAL_SET_UNUSED(v) do { \
+ (v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \
+ } while (0)
#define DUK_TVAL_SET_NULL(v) do { \
(v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \
} while (0)
@@ -6291,12 +6278,17 @@ typedef union duk_double_union duk_tval;
/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */
#if defined(DUK_USE_FASTINT)
-#define DUK_TVAL_SET_DOUBLE(v,d) DUK_DBLUNION_SET_DOUBLE((v), (d))
+#define DUK_TVAL_SET_DOUBLE(v,d) do { \
+ duk_double_t duk__dblval; \
+ duk__dblval = (d); \
+ DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \
+ DUK_DBLUNION_SET_DOUBLE((v), duk__dblval); \
+ } while (0)
#define DUK_TVAL_SET_FASTINT(v,i) DUK__TVAL_SET_FASTINT((v), (i))
#define DUK_TVAL_SET_FASTINT_I32(v,i) DUK__TVAL_SET_FASTINT_I32((v), (i))
#define DUK_TVAL_SET_FASTINT_U32(v,i) DUK__TVAL_SET_FASTINT_U32((v), (i))
#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) duk_tval_set_number_chkfast((v), (d))
-#define DUK_TVAL_SET_NUMBER(v,d) DUK_DBLUNION_SET_DOUBLE((v), (d))
+#define DUK_TVAL_SET_NUMBER(v,d) DUK_TVAL_SET_DOUBLE((v), (d))
#define DUK_TVAL_CHKFAST_INPLACE(v) do { \
duk_tval *duk__tv; \
duk_double_t duk__d; \
@@ -6307,9 +6299,14 @@ typedef union duk_double_union duk_tval;
} \
} while (0)
#else
-#define DUK_TVAL_SET_NUMBER(v,d) DUK_DBLUNION_SET_DOUBLE((v), (d))
-#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) DUK_TVAL_SET_NUMBER((v), (d))
-#define DUK_TVAL_SET_DOUBLE(v,d) DUK_TVAL_SET_NUMBER((v), (d))
+#define DUK_TVAL_SET_DOUBLE(v,d) do { \
+ duk_double_t duk__dblval; \
+ duk__dblval = (d); \
+ DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \
+ DUK_DBLUNION_SET_DOUBLE((v), duk__dblval); \
+ } while (0)
+#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) DUK_TVAL_SET_DOUBLE((v), (d))
+#define DUK_TVAL_SET_NUMBER(v,d) DUK_TVAL_SET_DOUBLE((v), (d))
#define DUK_TVAL_CHKFAST_INPLACE(v) do { } while (0)
#endif
@@ -6349,8 +6346,7 @@ typedef union duk_double_union duk_tval;
#define DUK_TVAL_GET_TAG(v) ((duk_small_uint_t)
(v)->us[DUK_DBL_IDX_US0])
#define DUK_TVAL_IS_UNDEFINED(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_UNDEFINED)
-#define DUK_TVAL_IS_UNDEFINED_ACTUAL(v) ((v)->ui[DUK_DBL_IDX_UI0] ==
DUK_XTAG_UNDEFINED_ACTUAL)
-#define DUK_TVAL_IS_UNDEFINED_UNUSED(v) ((v)->ui[DUK_DBL_IDX_UI0] ==
DUK_XTAG_UNDEFINED_UNUSED)
+#define DUK_TVAL_IS_UNUSED(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_UNUSED)
#define DUK_TVAL_IS_NULL(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_NULL)
#define DUK_TVAL_IS_BOOLEAN(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_BOOLEAN)
#define DUK_TVAL_IS_BOOLEAN_TRUE(v) ((v)->ui[DUK_DBL_IDX_UI0] ==
DUK_XTAG_BOOLEAN_TRUE)
@@ -6370,6 +6366,7 @@ typedef union duk_double_union duk_tval;
#define DUK_TVAL_IS_DOUBLE(v) DUK_TVAL_IS_NUMBER((v))
#endif
+/* This is performance critical because it appears in every DECREF. */
#define DUK_TVAL_IS_HEAP_ALLOCATED(v) (DUK_TVAL_GET_TAG((v)) >= DUK_TAG_STRING)
#if defined(DUK_USE_FASTINT)
@@ -6423,9 +6420,10 @@ struct duk_tval_struct {
#define DUK_TAG_BOOLEAN 4
#define DUK_TAG_POINTER 5
#define DUK_TAG_LIGHTFUNC 6
-#define DUK_TAG_STRING 7
-#define DUK_TAG_OBJECT 8
-#define DUK_TAG_BUFFER 9
+#define DUK_TAG_UNUSED 7 /* marker; not actual tagged type */
+#define DUK_TAG_STRING 8 /* first heap allocated, match bit boundary */
+#define DUK_TAG_OBJECT 9
+#define DUK_TAG_BUFFER 10
/* DUK__TAG_NUMBER is intentionally first, as it is the default clause in code
* to support the 8-byte representation. Further, it is a non-heap-allocated
@@ -6434,14 +6432,12 @@ struct duk_tval_struct {
*/
/* setters */
-#define DUK_TVAL_SET_UNDEFINED_ACTUAL(tv) do { \
+#define DUK_TVAL_SET_UNDEFINED(tv) do { \
(tv)->t = DUK_TAG_UNDEFINED; \
- (tv)->v.i = 0; \
} while (0)
-#define DUK_TVAL_SET_UNDEFINED_UNUSED(tv) do { \
- (tv)->t = DUK_TAG_UNDEFINED; \
- (tv)->v.i = 1; \
+#define DUK_TVAL_SET_UNUSED(tv) do { \
+ (tv)->t = DUK_TAG_UNUSED; \
} while (0)
#define DUK_TVAL_SET_NULL(tv) do { \
@@ -6488,7 +6484,7 @@ struct duk_tval_struct {
(tv)->t = DUK__TAG_NUMBER; \
(tv)->v.d = (val); \
} while (0)
-#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) \
+#define DUK_TVAL_SET_NUMBER_CHKFAST(tv,d) \
DUK_TVAL_SET_NUMBER((tv), (d))
#define DUK_TVAL_SET_DOUBLE(v,d) \
DUK_TVAL_SET_NUMBER((tv), (d))
@@ -6566,8 +6562,7 @@ struct duk_tval_struct {
/* decoding */
#define DUK_TVAL_GET_TAG(tv) ((tv)->t)
#define DUK_TVAL_IS_UNDEFINED(tv) ((tv)->t == DUK_TAG_UNDEFINED)
-#define DUK_TVAL_IS_UNDEFINED_ACTUAL(tv) (((tv)->t == DUK_TAG_UNDEFINED) &&
((tv)->v.i == 0))
-#define DUK_TVAL_IS_UNDEFINED_UNUSED(tv) (((tv)->t == DUK_TAG_UNDEFINED) &&
((tv)->v.i != 0))
+#define DUK_TVAL_IS_UNUSED(tv) ((tv)->t == DUK_TAG_UNUSED)
#define DUK_TVAL_IS_NULL(tv) ((tv)->t == DUK_TAG_NULL)
#define DUK_TVAL_IS_BOOLEAN(tv) ((tv)->t == DUK_TAG_BOOLEAN)
#define DUK_TVAL_IS_BOOLEAN_TRUE(tv) (((tv)->t == DUK_TAG_BOOLEAN) &&
((tv)->v.i != 0))
@@ -6587,7 +6582,15 @@ struct duk_tval_struct {
#define DUK_TVAL_IS_OBJECT(tv) ((tv)->t == DUK_TAG_OBJECT)
#define DUK_TVAL_IS_BUFFER(tv) ((tv)->t == DUK_TAG_BUFFER)
+/* This is performance critical because it's needed for every DECREF.
+ * Take advantage of the fact that the first heap allocated tag is 8,
+ * so that bit 3 is set for all heap allocated tags (and never set for
+ * non-heap-allocated tags).
+ */
+#if 0
#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) ((tv)->t >= DUK_TAG_STRING)
+#endif
+#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) ((tv)->t & 0x08)
#if defined(DUK_USE_FASTINT)
#if 0
@@ -6987,6 +6990,250 @@ struct duk_heaphdr_string {
} \
} while (0)
+/*
+ * Macros to set a duk_tval and update refcount of the target (decref the
+ * old value and incref the new value if necessary). This is both performance
+ * and footprint critical; any changes made should be measured for size/speed.
+ */
+
+#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_UNDEFINED(tv__dst); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_UNUSED(tv__dst); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_NULL(tv__dst); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_NUMBER_CHKFAST(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_NAN(tv__dst); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#if defined(DUK_USE_FASTINT)
+#define DUK_TVAL_SET_FASTINT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_FASTINT(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#define DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_FASTINT_I32(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#define DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_FASTINT_U32(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+#endif /* DUK_USE_FASTINT */
+
+#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_STRING(tv__dst, (newval)); \
+ DUK_HSTRING_INCREF((thr), (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \
+ DUK_HOBJECT_INCREF((thr), (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \
+ DUK_HBUFFER_INCREF((thr), (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_POINTER(tv__dst, (newval)); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups,
+ * etc, so it's very important for performance.
+ *
+ * NOTE: the source and destination duk_tval pointers may be the same, and
+ * the macros MUST deal with that correctly.
+ */
+
+/* Original idiom used. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF((thr), tv__src); \
+ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+#if 0 /* XXX: to optimize and measure */
+/* Original idiom but with forced fast refcount macros. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT0F(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF_FAST((thr), tv__src); \
+ DUK_TVAL_DECREF_FAST((thr), &tv__tmp); /* side effects */ \
+ } while (0)
+
+/* Use 'h__obj' temporary to avoid a full duk_tval copy. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ if (DUK_TVAL_IS_HEAP_ALLOCATED(tv__dst)) { \
+ h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \
+ DUK_ASSERT(h__obj != NULL); \
+ } else { \
+ h__obj = NULL; \
+ } \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF((thr), tv__src); \
+ if (h__obj != NULL) { \
+ DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \
+ } \
+ } while (0)
+
+/* Use 'h__obj' temporary to avoid a full duk_tval copy. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT1A(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ if (DUK_UNLIKELY(DUK_TVAL_IS_HEAP_ALLOCATED(tv__dst))) { \
+ h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \
+ DUK_ASSERT(h__obj != NULL); \
+ } else { \
+ h__obj = NULL; \
+ } \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF_FAST((thr), tv__src); \
+ if (DUK_UNLIKELY(h__obj != NULL)) { \
+ DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \
+ } \
+ } while (0)
+
+/* Avoid rechecking 'h__obj'. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT2(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ if (DUK_TVAL_IS_HEAP_ALLOCATED(tv__dst)) { \
+ h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \
+ DUK_ASSERT(h__obj != NULL); \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF((thr), tv__src); \
+ DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \
+ } else { \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF((thr), tv__src); \
+ } \
+ } while (0)
+
+/* Avoid rechecking 'h__obj'. */
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT3(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ if (DUK_UNLIKELY(DUK_TVAL_IS_HEAP_ALLOCATED(tv__dst))) { \
+ h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \
+ DUK_ASSERT(h__obj != NULL); \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF_FAST((thr), tv__src); \
+ DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \
+ } else { \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_TVAL_INCREF_FAST((thr), tv__src); \
+ } \
+ } while (0)
+#endif
+
+/* XXX: no optimized variants yet */
+#define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0
+#define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0
+#define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0
+#define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0
+#define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0
+#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0
+#define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0
+#define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0
+#if defined(DUK_USE_FASTINT)
+#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_FASTINT_UPDREF_ALT0
+#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0
+#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0
+#endif /* DUK_USE_FASTINT */
+#define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0
+#define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0
+#define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0
+#define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0
+#define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0
+
+#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
+/* Optimized for speed. */
+#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#else
+/* Optimized for size. */
+#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#endif
+
#else /* DUK_USE_REFERENCE_COUNTING */
#define DUK_TVAL_INCREF_FAST(thr,v) do {} while (0) /* nop */
@@ -7018,6 +7265,128 @@ struct duk_heaphdr_string {
#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */
+#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_UNDEFINED(tv__dst); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_UNUSED(tv__dst); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_NULL(tv__dst); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_NUMBER_CHKFAST(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_NAN(tv__dst); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#if defined(DUK_USE_FASTINT)
+#define DUK_TVAL_SET_FASTINT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_FASTINT(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#define DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_FASTINT_I32(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#define DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_FASTINT_U32(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+#endif /* DUK_USE_FASTINT */
+
+#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_STRING(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \
+ duk_tval *tv__dst; tv__dst = (tvptr_dst); \
+ DUK_TVAL_SET_POINTER(tv__dst, (newval)); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \
+ duk_tval *tv__dst, *tv__src; \
+ tv__dst = (tvptr_dst); tv__src = (tvptr_src); \
+ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \
+ DUK_UNREF((thr)); \
+ } while (0)
+
+#define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0
+#define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0
+#define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0
+#define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0
+#define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0
+#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0
+#define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0
+#define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0
+#if defined(DUK_USE_FASTINT)
+#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_FASTINT_UPDREF_ALT0
+#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0
+#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0
+#endif /* DUK_USE_FASTINT */
+#define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0
+#define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0
+#define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0
+#define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0
+#define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0
+
+#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0
+#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0
+
#endif /* DUK_USE_REFERENCE_COUNTING */
#endif /* DUK_HEAPHDR_H_INCLUDED */
@@ -7122,10 +7491,16 @@ DUK_INTERNAL_DECL void *duk_get_voidptr(duk_context *ctx,
duk_idx_t index);
#endif
DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t index);
+#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */
+DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t index);
+#endif
+
DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index,
duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped); /* out_clamped=NULL,
RangeError if outside range */
DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t index,
duk_int_t minval, duk_int_t maxval);
DUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t index,
duk_int_t minval, duk_int_t maxval);
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index);
+#endif
DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t index);
DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t index);
@@ -7142,9 +7517,6 @@ DUK_INTERNAL_DECL duk_hnativefunction
*duk_require_hnativefunction(duk_context *
DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_or_lfunc(duk_context *ctx, duk_idx_t
index);
DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_or_lfunc_coerce(duk_context *ctx,
duk_idx_t index);
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-DUK_INTERNAL_DECL void duk_push_unused(duk_context *ctx);
-#endif
DUK_INTERNAL_DECL void duk_push_hstring(duk_context *ctx, duk_hstring *h);
DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t
stridx);
DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h);
@@ -7166,7 +7538,7 @@ DUK_INTERNAL_DECL void
duk_push_c_function_noconstruct_noexotic(duk_context *ctx
DUK_INTERNAL_DECL void duk_push_string_funcptr(duk_context *ctx, duk_uint8_t *ptr,
duk_size_t sz);
DUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_context *ctx, duk_tval *tv);
DUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_context *ctx, duk_tval *tv);
-DUK_INTERNAL_DECL duk_hbufferobject *duk_push_bufferobject(duk_context *ctx, duk_uint_t
hobject_flags_and_class, duk_small_int_t prototype_bidx);
+DUK_INTERNAL_DECL duk_hbufferobject *duk_push_bufferobject_raw(duk_context *ctx,
duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index,
duk_small_int_t stridx); /* [] -> [val] */
DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_index,
duk_small_int_t stridx); /* [val] -> [] */
@@ -7436,7 +7808,7 @@ DUK_INTERNAL_DECL duk_ucodepoint_t
duk_hstring_char_code_at_raw(duk_hthread *thr
#define DUK_HOBJECT_FLAG_THREAD DUK_HEAPHDR_USER_FLAG(7) /* object is a
thread (duk_hthread) */
#define DUK_HOBJECT_FLAG_ARRAY_PART DUK_HEAPHDR_USER_FLAG(8) /* object has
an array part (a_size may still be 0) */
#define DUK_HOBJECT_FLAG_STRICT DUK_HEAPHDR_USER_FLAG(9) /* function:
function object is strict */
-#define DUK_HOBJECT_FLAG_NOTAIL DUK_HEAPHDR_USER_FLAG(10) /* function:
function must not be tailcalled */
+#define DUK_HOBJECT_FLAG_NOTAIL DUK_HEAPHDR_USER_FLAG(10) /* function:
function must not be tail called */
#define DUK_HOBJECT_FLAG_NEWENV DUK_HEAPHDR_USER_FLAG(11) /* function:
create new environment when called (see duk_hcompiledfunction) */
#define DUK_HOBJECT_FLAG_NAMEBINDING DUK_HEAPHDR_USER_FLAG(12) /* function:
create binding for func name (function templates only, used for named function
expressions) */
#define DUK_HOBJECT_FLAG_CREATEARGS DUK_HEAPHDR_USER_FLAG(13) /* function:
create an arguments object on function call */
@@ -7799,8 +8171,8 @@ DUK_INTERNAL_DECL duk_ucodepoint_t
duk_hstring_char_code_at_raw(duk_hthread *thr
(set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \
(set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \
(set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \
- sizeof(duk_uint8_t) * (n_ent) + \
- DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \
+ sizeof(duk_uint8_t) * (n_ent) + \
+ DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \
(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \
} while (0)
#elif defined(DUK_USE_HOBJECT_LAYOUT_3)
@@ -8008,7 +8380,7 @@ DUK_INTERNAL_DECL duk_ucodepoint_t
duk_hstring_char_code_at_raw(duk_hthread *thr
#endif
/* note: this updates refcounts */
-#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype((thr),
(h), (p))
+#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p)
duk_hobject_set_prototype_updref((thr), (h), (p))
/*
* Resizing and hash behavior
@@ -8296,7 +8668,7 @@ DUK_INTERNAL_DECL duk_ret_t
duk_hobject_get_enumerated_keys(duk_context *ctx, du
DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
get_value);
/* macros */
-DUK_INTERNAL_DECL void duk_hobject_set_prototype(duk_hthread *thr, duk_hobject *h,
duk_hobject *p);
+DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h,
duk_hobject *p);
/* finalization */
DUK_INTERNAL_DECL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj);
@@ -8625,8 +8997,9 @@ struct duk_hnativefunction {
} else { \
/* No assertions for offset or length; in particular, \
* it's OK for length to be longer than underlying \
- * buffer. \
+ * buffer. Just ensure they don't wrap when added. \
*/ \
+ DUK_ASSERT((h)->offset + (h)->length >= (h)->offset); \
} \
} while (0)
@@ -8710,7 +9083,9 @@ struct duk_hbufferobject {
duk_uint8_t is_view;
};
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL_DECL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject
*h_bufobj, duk_uint_t len);
+#endif
DUK_INTERNAL_DECL void duk_hbufferobject_push_validated_read(duk_context *ctx,
duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx,
duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
@@ -8767,7 +9142,7 @@ DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context
*ctx, duk_h
*/
#define DUK_ACT_FLAG_STRICT (1 << 0) /* function executes in strict
mode */
-#define DUK_ACT_FLAG_TAILCALLED (1 << 1) /* activation has tailcalled one
or more times */
+#define DUK_ACT_FLAG_TAILCALLED (1 << 1) /* activation has tail called one
or more times */
#define DUK_ACT_FLAG_CONSTRUCT (1 << 2) /* function executes as a
constructor (called via "new") */
#define DUK_ACT_FLAG_PREVENT_YIELD (1 << 3) /* activation prevents yield
(native call or "new") */
#define DUK_ACT_FLAG_DIRECT_EVAL (1 << 4) /* activation is a direct eval
call */
@@ -8873,6 +9248,13 @@ DUK_INTERNAL_DECL void
duk_hbufferobject_validated_write(duk_context *ctx, duk_h
* diagnose behavior so it's worth checking even when the check is not 100%.
*/
+#if defined(DUK_USE_PREFER_SIZE)
+#define DUK_ASSERT_CTX_VSSIZE(ctx) /*nop*/
+#else
+#define DUK_ASSERT_CTX_VSSIZE(ctx) \
+ DUK_ASSERT((duk_size_t) (((duk_hthread *) (ctx))->valstack_end - ((duk_hthread *)
(ctx))->valstack) == \
+ ((duk_hthread *) (ctx))->valstack_size)
+#endif
#define DUK_ASSERT_CTX_VALID(ctx) do { \
DUK_ASSERT((ctx) != NULL); \
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) (ctx)) == DUK_HTYPE_OBJECT); \
@@ -8883,6 +9265,8 @@ DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context
*ctx, duk_h
DUK_ASSERT(((duk_hthread *) (ctx))->valstack_end >= ((duk_hthread *)
(ctx))->valstack); \
DUK_ASSERT(((duk_hthread *) (ctx))->valstack_top >= ((duk_hthread *)
(ctx))->valstack); \
DUK_ASSERT(((duk_hthread *) (ctx))->valstack_top >= ((duk_hthread *)
(ctx))->valstack_bottom); \
+ DUK_ASSERT(((duk_hthread *) (ctx))->valstack_end >= ((duk_hthread *)
(ctx))->valstack_top); \
+ DUK_ASSERT_CTX_VSSIZE((ctx)); \
} while (0)
/*
@@ -8906,11 +9290,11 @@ struct duk_activation {
duk_hobject *prev_caller;
#endif
- duk_small_uint_t flags;
- duk_uint32_t pc; /* next instruction to execute */
+ duk_instr_t *curr_pc; /* next instruction to execute (points to 'func'
bytecode, stable pointer), NULL for native calls */
#if defined(DUK_USE_DEBUGGER_SUPPORT)
duk_uint32_t prev_line; /* needed for stepping */
#endif
+ duk_small_uint_t flags;
/* idx_bottom and idx_retval are only used for book-keeping of
* Ecmascript-initiated calls, to allow returning to an Ecmascript
@@ -8949,56 +9333,71 @@ struct duk_activation {
struct duk_catcher {
duk_hstring *h_varname; /* borrowed reference to catch variable name (or NULL if
none) */
/* (reference is valid as long activation exists) */
+ duk_instr_t *pc_base; /* resume execution from pc_base or pc_base+1 (points to
'func' bytecode, stable pointer) */
duk_size_t callstack_index; /* callstack index of related activation */
duk_size_t idx_base; /* idx_base and idx_base+1 get completion value and type
*/
- duk_uint32_t pc_base; /* resume execution from pc_base or pc_base+1 */
duk_uint32_t flags; /* type and control flags, label number */
};
struct duk_hthread {
- /* shared object part */
+ /* Shared object part */
duk_hobject obj;
- /* backpointers */
+ /* Pointer to bytecode executor's 'curr_pc' variable. Used to copy
+ * the current PC back into the topmost activation when activation
+ * state is about to change (or "syncing" is otherwise needed). This
+ * is rather awkward but important for performance, see execution.rst.
+ */
+ duk_instr_t **ptr_curr_pc;
+
+ /* Backpointers. */
duk_heap *heap;
- /* current strictness flag: affects API calls */
+ /* Current strictness flag: affects API calls. */
duk_uint8_t strict;
+
+ /* Thread state. */
duk_uint8_t state;
duk_uint8_t unused1;
duk_uint8_t unused2;
- /* sanity limits */
+ /* Sanity limits for stack sizes. */
duk_size_t valstack_max;
duk_size_t callstack_max;
duk_size_t catchstack_max;
- /* XXX: valstack, callstack, and catchstack are currently assumed
+ /* XXX: Valstack, callstack, and catchstack are currently assumed
* to have non-NULL pointers. Relaxing this would not lead to big
* benefits (except perhaps for terminated threads).
*/
- /* value stack: these are expressed as pointers for faster stack manipulation */
+ /* Value stack: these are expressed as pointers for faster stack manipulation.
+ * [valstack,valstack_top[ is GC-reachable, [valstack_top,valstack_end[ is
+ * not GC-reachable but kept initialized as 'undefined'.
+ */
duk_tval *valstack; /* start of valstack allocation */
duk_tval *valstack_end; /* end of valstack allocation (exclusive) */
duk_tval *valstack_bottom; /* bottom of current frame */
duk_tval *valstack_top; /* top of current frame (exclusive) */
+#if !defined(DUK_USE_PREFER_SIZE)
+ duk_size_t valstack_size; /* cached: valstack_end - valstack (in entries,
not bytes) */
+#endif
- /* call stack */
+ /* Call stack. [0,callstack_top[ is GC reachable. */
duk_activation *callstack;
duk_size_t callstack_size; /* allocation size */
duk_size_t callstack_top; /* next to use, highest used is top - 1 */
duk_size_t callstack_preventcount; /* number of activation records in callstack
preventing a yield */
- /* catch stack */
+ /* Catch stack. [0,catchstack_top[ is GC reachable. */
duk_catcher *catchstack;
duk_size_t catchstack_size; /* allocation size */
duk_size_t catchstack_top; /* next to use, highest used is top - 1 */
- /* yield/resume book-keeping */
+ /* Yield/resume book-keeping. */
duk_hthread *resumer; /* who resumed us (if any) */
- /* current compiler state (if any), used for augmenting SyntaxErrors */
+ /* Current compiler state (if any), used for augmenting SyntaxErrors. */
duk_compiler_ctx *compile_ctx;
#if defined(DUK_USE_INTERRUPT_COUNTER)
@@ -9022,7 +9421,7 @@ struct duk_hthread {
*/
duk_hobject *builtins[DUK_NUM_BUILTINS];
- /* convenience copies from heap/vm for faster access */
+ /* Convenience copies from heap/vm for faster access. */
#if defined(DUK_USE_HEAPPTR16)
duk_uint16_t *strs16;
#else
@@ -9051,6 +9450,13 @@ DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap
*heap, void *ud);
DUK_INTERNAL_DECL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud); /*
indirect allocs */
DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud); /*
indirect allocs */
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+DUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr,
duk_activation *act);
+#endif
+DUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr,
duk_activation *act);
+DUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);
+
#endif /* DUK_HTHREAD_H_INCLUDED */
#line 1 "duk_hbuffer.h"
/*
@@ -9069,17 +9475,23 @@ DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap
*heap, void *ud)
/*
* Flags
+ *
+ * Fixed buffer: 0
+ * Dynamic buffer: DUK_HBUFFER_FLAG_DYNAMIC
+ * External buffer: DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL
*/
-#define DUK_HBUFFER_FLAG_DYNAMIC DUK_HEAPHDR_USER_FLAG(0) /* buffer is
resizable */
+#define DUK_HBUFFER_FLAG_DYNAMIC DUK_HEAPHDR_USER_FLAG(0) /* buffer
is behind a pointer, dynamic or external */
+#define DUK_HBUFFER_FLAG_EXTERNAL DUK_HEAPHDR_USER_FLAG(1) /* buffer
pointer is to an externally allocated buffer */
#define DUK_HBUFFER_HAS_DYNAMIC(x)
DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)
+#define DUK_HBUFFER_HAS_EXTERNAL(x)
DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)
#define DUK_HBUFFER_SET_DYNAMIC(x)
DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)
+#define DUK_HBUFFER_SET_EXTERNAL(x)
DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)
#define DUK_HBUFFER_CLEAR_DYNAMIC(x)
DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)
-
-#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed
*) (x)) + 1))
+#define DUK_HBUFFER_CLEAR_EXTERNAL(x)
DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)
/*
* Misc defines
@@ -9140,6 +9552,11 @@ DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap
*heap, void *ud)
#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv) DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x),
(dv))
#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv) DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x),
(dv))
+#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))
+#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v) DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x),
(v))
+
+#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed
*) (x)) + 1))
+
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \
((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *)
(x))->h_extra16))
@@ -9159,19 +9576,58 @@ DUK_INTERNAL_DECL void *duk_hthread_get_catchstack_ptr(duk_heap
*heap, void *ud)
} while (0)
#endif
-/* Gets the actual buffer contents which matches the current allocation size
- * (may be NULL for zero size dynamic buffer).
+/* No pointer compression because pointer is potentially outside of
+ * Duktape heap.
+ */
+#if defined(DUK_USE_HEAPPTR16)
+#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \
+ ((void *) (x)->curr_alloc)
+#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v) do { \
+ (x)->curr_alloc = (void *) (v); \
+ } while (0)
+#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x) do { \
+ (x)->curr_alloc = (void *) NULL; \
+ } while (0)
+#else
+#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \
+ ((void *) (x)->curr_alloc)
+#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v) do { \
+ (x)->curr_alloc = (void *) (v); \
+ } while (0)
+#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x) do { \
+ (x)->curr_alloc = (void *) NULL; \
+ } while (0)
+#endif
+
+/* Get a pointer to the current buffer contents (matching current allocation
+ * size). May be NULL for zero size dynamic/external buffer.
+ */
+#if defined(DUK_USE_HEAPPTR16)
+#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \
+ DUK_HBUFFER_HAS_DYNAMIC((x)) ? \
+ ( \
+ DUK_HBUFFER_HAS_EXTERNAL((x)) ? \
+ DUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \
+ DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \
+ ) : \
+ DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (x)) \
+ )
+#else
+/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external
+ * have the same layout so checking for fixed vs. dynamic (or external) is enough.
*/
#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \
DUK_HBUFFER_HAS_DYNAMIC((x)) ? \
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \
DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (x)) \
)
+#endif
/*
* Structs
*/
+/* Shared prefix for all buffer types. */
struct duk_hbuffer {
duk_heaphdr hdr;
@@ -9199,6 +9655,11 @@ struct duk_hbuffer {
* - a "void *" pointing to the current allocation
* - a duk_size_t indicating the full allocated size (always >= 'size')
*
+ * If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated
+ * by user code, so that Duktape won't be able to resize it and won't
+ * free it. This allows buffers to point to e.g. an externally
+ * allocated structure such as a frame buffer.
+ *
* Unlike strings, no terminator byte (NUL) is guaranteed after the
* data. This would be convenient, but would pad aligned user buffers
* unnecessarily upwards in size. For instance, if user code requested
@@ -9207,6 +9668,9 @@ struct duk_hbuffer {
*/
};
+/* Fixed buffer; data follows struct, with proper alignment guaranteed by
+ * struct size.
+ */
#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
#pragma pack(push, 8)
#endif
@@ -9260,6 +9724,10 @@ __attribute__ ((aligned (8)))
#pragma pack(pop)
#endif
+/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using
+ * heap allocation primitives. Also used for external buffers when low memory
+ * options are not used.
+ */
struct duk_hbuffer_dynamic {
duk_heaphdr hdr;
@@ -9285,11 +9753,30 @@ struct duk_hbuffer_dynamic {
*/
};
+/* External buffer with 'curr_alloc' managed by user code and pointing to an
+ * arbitrary address. When heap pointer compression is not used, this struct
+ * has the same layout as duk_hbuffer_dynamic.
+ */
+struct duk_hbuffer_external {
+ duk_heaphdr hdr;
+
+#if defined(DUK_USE_BUFLEN16)
+ /* Stored in duk_heaphdr unused flags. */
+#else
+ duk_size_t size;
+#endif
+
+ /* Cannot be compressed as a heap pointer because may point to
+ * an arbitrary address.
+ */
+ void *curr_alloc; /* may be NULL if alloc_size == 0 */
+};
+
/*
* Prototypes
*/
-DUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size,
duk_small_uint_t flags);
+DUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size,
duk_small_uint_t flags, void **out_bufdata);
DUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud); /*
indirect allocs */
/* dynamic buffer ops */
@@ -9351,13 +9838,13 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr,
duk_hbuffer_dynamic *
*/
#define DUK_LJ_TYPE_UNKNOWN 0 /* unused */
-#define DUK_LJ_TYPE_RETURN 1 /* value1 -> return value */
-#define DUK_LJ_TYPE_THROW 2 /* value1 -> error object */
-#define DUK_LJ_TYPE_BREAK 3 /* value1 -> label number */
-#define DUK_LJ_TYPE_CONTINUE 4 /* value1 -> label number */
-#define DUK_LJ_TYPE_YIELD 5 /* value1 -> yield value, iserror -> error /
normal */
-#define DUK_LJ_TYPE_RESUME 6 /* value1 -> resume value, value2 -> resumee
thread, iserror -> error/normal */
-#define DUK_LJ_TYPE_NORMAL 7 /* pseudo-type to indicate a normal continuation
(for 'finally' rethrowing) */
+#define DUK_LJ_TYPE_THROW 1 /* value1 -> error object */
+#define DUK_LJ_TYPE_YIELD 2 /* value1 -> yield value, iserror -> error /
normal */
+#define DUK_LJ_TYPE_RESUME 3 /* value1 -> resume value, value2 -> resumee
thread, iserror -> error/normal */
+#define DUK_LJ_TYPE_BREAK 4 /* value1 -> label number, pseudo-type to
indicate a break continuation (for ENDFIN) */
+#define DUK_LJ_TYPE_CONTINUE 5 /* value1 -> label number, pseudo-type to
indicate a continue continuation (for ENDFIN) */
+#define DUK_LJ_TYPE_RETURN 6 /* value1 -> return value, pseudo-type to
indicate a return continuation (for ENDFIN) */
+#define DUK_LJ_TYPE_NORMAL 7 /* no value, pseudo-type to indicate a normal
continuation (for ENDFIN) */
/*
* Mark-and-sweep flags
@@ -9392,31 +9879,6 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr,
duk_hbuffer_dynamic *
* Other heap related defines
*/
-/* Maximum duk_handle_call / duk_handle_safe_call depth. Note that this
- * does not limit bytecode executor internal call depth at all (e.g.
- * for Ecmascript-to-Ecmascript calls, thread yields/resumes, etc).
- * There is a separate callstack depth limit for threads.
- */
-
-#if defined(DUK_USE_DEEP_C_STACK)
-#define DUK_HEAP_DEFAULT_CALL_RECURSION_LIMIT 1000 /* assuming 0.5 kB
between calls, about 500kB of stack */
-#else
-#define DUK_HEAP_DEFAULT_CALL_RECURSION_LIMIT 60 /* assuming 0.5 kB
between calls, about 30kB of stack */
-#endif
-
-/* Mark-and-sweep C recursion depth for marking phase; if reached,
- * mark object as a TEMPROOT and use multi-pass marking.
- */
-#if defined(DUK_USE_MARK_AND_SWEEP)
-#if defined(DUK_USE_GC_TORTURE)
-#define DUK_HEAP_MARK_AND_SWEEP_RECURSION_LIMIT 3
-#elif defined(DUK_USE_DEEP_C_STACK)
-#define DUK_HEAP_MARK_AND_SWEEP_RECURSION_LIMIT 256
-#else
-#define DUK_HEAP_MARK_AND_SWEEP_RECURSION_LIMIT 32
-#endif
-#endif
-
/* Mark-and-sweep interval is relative to combined count of objects and
* strings kept in the heap during the latest mark-and-sweep pass.
* Fixed point .8 multiplier and .0 adder. Trigger count (interval) is
@@ -9758,6 +10220,7 @@ struct duk_heap {
duk_bool_t dbg_processing; /* currently processing messages or breakpoints:
don't enter message processing recursively (e.g. no breakpoints when processing
debugger eval) */
duk_bool_t dbg_paused; /* currently paused: talk with debug client
until step/resume */
duk_bool_t dbg_state_dirty; /* resend state next time executor is about to
run */
+ duk_bool_t dbg_force_restart; /* force executor restart to recheck
breakpoints; used to handle function returns (see GH-303) */
duk_small_uint_t dbg_step_type; /* step type: none, step into, step over, step
out */
duk_hthread *dbg_step_thread; /* borrowed; NULL if no step state (NULLed in
unwind) */
duk_size_t dbg_step_csindex; /* callstack index */
@@ -9838,7 +10301,9 @@ DUK_INTERNAL_DECL duk_hstring *duk_heap_string_lookup_u32(duk_heap
*heap, duk_ui
#endif
DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_u32(duk_heap *heap, duk_uint32_t
val);
DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_u32_checked(duk_hthread *thr,
duk_uint32_t val);
+#if defined(DUK_USE_REFERENCE_COUNTING)
DUK_INTERNAL_DECL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h);
+#endif
#if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_MS_STRINGTABLE_RESIZE)
DUK_INTERNAL_DECL void duk_heap_force_strtab_resize(duk_heap *heap);
#endif
@@ -9917,6 +10382,7 @@ DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap,
const duk_uin
#define DUK_DBG_CMD_PRINT 0x02
#define DUK_DBG_CMD_ALERT 0x03
#define DUK_DBG_CMD_LOG 0x04
+#define DUK_DBG_CMD_THROW 0x05
/* Initiated by debug client */
#define DUK_DBG_CMD_BASICINFO 0x10
@@ -9984,7 +10450,9 @@ DUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr);
DUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr);
DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal);
+DUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t
use_prev_pc);
DUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
no_block);
DUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring
*filename, duk_uint32_t line);
@@ -10365,9 +10833,9 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) do { \
- duk_double_union assert_tmp_du; \
- assert_tmp_du.d = (dval); \
- DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&assert_tmp_du)); \
+ duk_double_union duk__assert_tmp_du; \
+ duk__assert_tmp_du.d = (dval); \
+ DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \
} while (0)
#else
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */
@@ -10666,6 +11134,13 @@ extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[348];
extern const duk_uint8_t duk_unicode_caseconv_uc[1288];
extern const duk_uint8_t duk_unicode_caseconv_lc[616];
+/* FIXME: CONDITIONAL */
+/*
+ * Automatically generated by extract_caseconv.py, do not edit!
+ */
+
+extern const duk_uint16_t duk_unicode_re_canon_lookup[65536];
+
/*
* Extern
*/
@@ -10712,15 +11187,6 @@ DUK_INTERNAL_DECL duk_small_int_t
duk_unicode_re_is_wordchar(duk_codepoint_t cp)
#ifndef DUK_JSON_H_INCLUDED
#define DUK_JSON_H_INCLUDED
-/* Object/array recursion limit (to protect C stack) */
-#if defined(DUK_USE_DEEP_C_STACK)
-#define DUK_JSON_ENC_RECURSION_LIMIT 1000
-#define DUK_JSON_DEC_RECURSION_LIMIT 1000
-#else
-#define DUK_JSON_ENC_RECURSION_LIMIT 100
-#define DUK_JSON_DEC_RECURSION_LIMIT 100
-#endif
-
/* Encoding/decoding flags */
#define DUK_JSON_FLAG_ASCII_ONLY (1 << 0) /* escape any non-ASCII
characters */
#define DUK_JSON_FLAG_AVOID_KEY_QUOTES (1 << 1) /* avoid key quotes when
key is an ASCII Identifier */
@@ -10798,7 +11264,7 @@ typedef struct {
#define DUK_CALL_FLAG_IGNORE_RECLIMIT (1 << 1) /* duk_handle_call: call
ignores C recursion limit (for errhandler calls) */
#define DUK_CALL_FLAG_CONSTRUCTOR_CALL (1 << 2) /* duk_handle_call:
constructor call (i.e. called as 'new Foo()') */
#define DUK_CALL_FLAG_IS_RESUME (1 << 3) /*
duk_handle_ecma_call_setup: setup for a resume() */
-#define DUK_CALL_FLAG_IS_TAILCALL (1 << 4) /*
duk_handle_ecma_call_setup: setup for a tailcall */
+#define DUK_CALL_FLAG_IS_TAILCALL (1 << 4) /*
duk_handle_ecma_call_setup: setup for a tail call */
#define DUK_CALL_FLAG_DIRECT_EVAL (1 << 5) /* call is a direct eval
call */
/* Flags for duk_js_equals_helper(). */
@@ -11252,7 +11718,7 @@ DUK_INTERNAL const char *duk_str_buffer_too_long = "buffer
too long";
DUK_INTERNAL const char *duk_str_sprintf_too_long = "sprintf message too
long";
DUK_INTERNAL const char *duk_str_alloc_failed = "alloc failed";
DUK_INTERNAL const char *duk_str_pop_too_many = "attempt to pop too many
entries";
-DUK_INTERNAL const char *duk_str_buffer_not_dynamic = "buffer is not dynamic";
+DUK_INTERNAL const char *duk_str_wrong_buffer_type = "wrong buffer type";
DUK_INTERNAL const char *duk_str_failed_to_extend_valstack = "failed to extend
valstack";
DUK_INTERNAL const char *duk_str_encode_failed = "encode failed";
DUK_INTERNAL const char *duk_str_decode_failed = "decode failed";
@@ -11866,7 +12332,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
156,80,0,70,82,113,64,1,89,41,197,0,6,100,39,20,0,29,142,156,80,0,134,50,
98,243,21,53,121,136,160,144,0,22,26,120,24,73,197,0,9,96,167,20,0,41,128,
156,80,0,181,250,113,64,3,1,255,254,0,81,20,100,47,145,216,23,255,240,0,11,
-255,248,0,3,255,252,81,252,0,0,0,0,8,1,220,68,0,129,167,1,26,144,9,165,0,
+255,248,0,3,255,252,81,252,0,0,0,0,8,4,252,68,0,129,167,1,26,144,9,165,0,
26,177,199,197,132,30,147,16,120,86,65,217,80,240,232,164,120,114,80,60,52,
39,32,84,223,192,15,59,30,129,156,115,6,81,160,7,253,40,0,5,81,252,0,1,255,
78,0,84,113,96,128,0,209,69,128,21,87,240,0,7,253,72,1,81,221,66,0,3,69,
@@ -11898,16 +12364,90 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
106,0,
};
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = {
-40,102,117,110,99,116,105,111,110,40,100,44,97,41,123,102,117,110,99,116,
-105,111,110,32,98,40,97,44,98,44,99,41,123,79,98,106,101,99,116,46,100,101,
-102,105,110,101,80,114,111,112,101,114,116,121,40,97,44,98,44,123,118,97,
-108,117,101,58,99,44,119,114,105,116,97,98,108,101,58,33,48,44,101,110,117,
-109,101,114,97,98,108,101,58,33,49,44,99,111,110,102,105,103,117,114,97,98,
-108,101,58,33,48,125,41,125,98,40,97,46,76,111,103,103,101,114,44,34,99,
-108,111,103,34,44,110,101,119,32,97,46,76,111,103,103,101,114,40,34,67,34,
-41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,123,125,41,
-125,41,40,116,104,105,115,44,68,117,107,116,97,112,101,41,59,10,0,
+DUK_INTERNAL const duk_uint8_t duk_initjs_data[1757] = {
+47,42,10,32,42,32,32,73,110,105,116,32,99,111,100,101,32,102,111,114,32,
+108,101,103,97,99,121,32,99,111,109,112,97,116,105,98,105,108,105,116,121,
+46,10,32,42,10,32,42,32,32,67,111,109,112,97,116,105,98,105,108,105,116,
+121,32,112,114,111,112,101,114,116,105,101,115,32,47,32,119,114,97,112,112,
+101,114,32,102,117,110,99,116,105,111,110,115,32,104,101,114,101,32,97,108,
+108,111,119,32,68,117,107,116,97,112,101,32,116,111,32,114,101,109,97,105,
+110,10,32,42,32,32,99,111,109,112,97,116,105,98,108,101,32,102,111,114,32,
+117,115,101,114,32,99,111,100,101,32,119,104,101,110,32,99,111,114,101,32,
+102,101,97,116,117,114,101,115,32,97,114,101,32,99,104,97,110,103,101,100,
+44,32,119,105,116,104,111,117,116,32,98,117,114,100,101,110,105,110,103,10,
+32,42,32,32,116,104,101,32,109,97,105,110,32,67,32,99,111,100,101,32,119,
+105,116,104,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32,115,116,
+117,102,102,46,10,32,42,10,32,42,32,32,84,104,105,115,32,102,105,108,101,
+32,105,115,32,109,105,110,105,102,105,101,100,32,119,105,116,104,32,85,103,
+108,105,102,121,74,83,32,111,114,32,116,104,101,32,99,108,111,115,117,114,
+101,32,99,111,109,112,105,108,101,114,46,32,32,66,111,116,104,32,119,105,
+108,108,10,32,42,32,32,114,101,110,97,109,101,32,118,97,114,105,97,98,108,
+101,115,44,32,114,101,109,111,118,101,32,99,111,109,109,101,110,116,115,44,
+32,97,110,100,32,97,114,101,32,99,108,101,118,101,114,32,101,110,111,117,
+103,104,32,116,111,32,100,114,111,112,32,97,110,121,10,32,42,32,32,34,105,
+102,32,40,102,97,108,115,101,41,32,123,32,46,46,46,32,125,34,32,98,108,111,
+99,107,115,32,97,108,116,111,103,101,116,104,101,114,44,32,115,111,32,116,
+104,97,116,39,115,32,97,110,32,101,102,102,101,99,116,105,118,101,32,119,
+97,121,32,116,111,10,32,42,32,32,100,105,115,97,98,108,101,32,99,117,114,
+114,101,110,116,108,121,32,117,110,110,101,101,100,101,100,32,99,111,100,
+101,46,10,32,42,47,10,10,40,102,117,110,99,116,105,111,110,40,71,44,32,68,
+41,32,123,10,32,32,32,32,39,117,115,101,32,115,116,114,105,99,116,39,59,10,
+10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,101,102,40,111,98,106,
+101,99,116,44,32,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,
+32,32,32,32,32,32,32,79,98,106,101,99,116,46,100,101,102,105,110,101,80,
+114,111,112,101,114,116,121,40,111,98,106,101,99,116,44,32,110,97,109,101,
+44,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,118,97,108,117,101,58,32,
+118,97,108,117,101,44,10,32,32,32,32,32,32,32,32,32,32,32,32,119,114,105,
+116,97,98,108,101,58,32,116,114,117,101,44,10,32,32,32,32,32,32,32,32,32,
+32,32,32,101,110,117,109,101,114,97,98,108,101,58,32,102,97,108,115,101,44,
+10,32,32,32,32,32,32,32,32,32,32,32,32,99,111,110,102,105,103,117,114,97,
+98,108,101,58,32,116,114,117,101,10,32,32,32,32,32,32,32,32,125,41,59,10,
+32,32,32,32,125,10,10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,
+101,102,68,40,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,32,
+32,32,32,32,32,32,100,101,102,40,68,44,32,110,97,109,101,44,32,118,97,108,
+117,101,41,59,10,32,32,32,32,125,10,10,32,32,32,32,47,47,32,67,111,109,112,
+97,116,105,98,105,108,105,116,121,32,102,111,114,32,39,99,111,110,115,111,
+108,101,46,108,111,103,39,46,10,32,32,32,32,105,102,32,40,102,97,108,115,
+101,41,32,123,10,32,32,32,32,32,32,32,32,99,111,110,115,111,108,101,32,61,
+32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,108,111,103,58,32,102,117,
+110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,112,114,105,110,116,40,65,114,114,97,121,46,112,114,111,116,
+111,116,121,112,101,46,106,111,105,110,46,99,97,108,108,40,97,114,103,117,
+109,101,110,116,115,44,32,39,32,39,41,41,59,10,32,32,32,32,32,32,32,32,32,
+32,32,32,125,10,32,32,32,32,32,32,32,32,125,59,10,32,32,32,32,125,10,10,32,
+32,32,32,47,47,32,68,117,107,116,97,112,101,46,108,105,110,101,40,41,32,
+119,97,115,32,114,101,109,111,118,101,100,32,105,110,32,68,117,107,116,97,
+112,101,32,48,46,49,49,46,48,44,32,104,101,114,101,39,115,32,97,110,32,101,
+120,97,109,112,108,101,10,32,32,32,32,47,47,32,114,101,112,108,97,99,101,
+109,101,110,116,32,117,115,101,114,32,99,111,100,101,32,99,111,117,108,100,
+32,117,115,101,46,10,32,32,32,32,105,102,32,40,102,97,108,115,101,41,32,
+123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,108,105,110,101,
+39,44,32,102,117,110,99,116,105,111,110,32,40,41,32,123,10,32,32,32,32,32,
+32,32,32,32,32,32,32,39,117,115,101,32,100,117,107,32,110,111,116,97,105,
+108,39,59,10,10,32,32,32,32,32,32,32,32,32,32,32,32,47,42,32,84,97,105,108,
+32,99,97,108,108,115,32,97,114,101,32,112,114,101,118,101,110,116,101,100,
+32,116,111,32,101,110,115,117,114,101,32,99,97,108,108,105,110,103,32,97,
+99,116,105,118,97,116,105,111,110,32,101,120,105,115,116,115,46,10,32,32,
+32,32,32,32,32,32,32,32,32,32,32,42,32,67,97,108,108,32,115,116,97,99,107,
+32,105,110,100,105,99,101,115,58,32,45,49,32,61,32,68,117,107,116,97,112,
+101,46,97,99,116,44,32,45,50,32,61,32,103,101,116,67,117,114,114,101,110,
+116,76,105,110,101,44,32,45,51,32,61,32,99,97,108,108,101,114,10,32,32,32,
+32,32,32,32,32,32,32,32,32,32,42,47,10,10,32,32,32,32,32,32,32,32,32,32,32,
+32,114,101,116,117,114,110,32,40,68,117,107,116,97,112,101,46,97,99,116,40,
+45,51,41,32,124,124,32,123,125,41,46,108,105,110,101,78,117,109,98,101,114,
+59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,10,10,32,32,32,
+32,47,47,32,76,111,103,103,101,114,32,111,98,106,101,99,116,32,102,111,114,
+32,67,32,99,111,100,101,32,112,114,111,118,105,100,101,100,32,98,121,32,
+105,110,105,116,32,99,111,100,101,32,110,111,119,46,10,32,32,32,32,105,102,
+32,40,116,114,117,101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,
+68,46,76,111,103,103,101,114,44,32,39,99,108,111,103,39,44,32,110,101,119,
+32,68,46,76,111,103,103,101,114,40,39,67,39,41,41,59,10,32,32,32,32,125,10,
+10,32,32,32,32,47,47,32,84,114,97,99,107,105,110,103,32,116,97,98,108,101,
+32,102,111,114,32,67,111,109,109,111,110,74,83,32,109,111,100,117,108,101,
+32,108,111,97,100,105,110,103,46,10,32,32,32,32,105,102,32,40,116,114,117,
+101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,109,
+111,100,76,111,97,100,101,100,39,44,32,123,125,41,59,10,32,32,32,32,125,10,
+125,41,40,116,104,105,115,44,32,68,117,107,116,97,112,101,41,59,10,0,
};
#endif /* DUK_USE_BUILTIN_INITJS */
#elif defined(DUK_USE_DOUBLE_BE)
@@ -12252,7 +12792,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
80,0,70,82,113,64,1,89,41,197,0,6,100,39,20,0,29,142,156,80,0,134,50,98,
243,21,53,121,136,160,144,0,22,26,120,24,73,197,0,9,96,167,20,0,41,128,156,
80,0,181,250,113,64,3,1,255,254,0,81,20,100,47,145,216,23,255,240,0,11,255,
-248,0,3,255,252,81,252,4,12,65,216,0,0,0,0,0,129,167,1,26,144,9,165,0,26,
+248,0,3,255,252,81,252,4,12,68,248,0,0,0,0,0,129,167,1,26,144,9,165,0,26,
177,199,197,132,30,147,16,120,86,65,217,80,240,232,164,120,114,80,60,52,39,
32,84,223,192,15,59,30,129,156,115,6,81,160,7,253,40,0,5,81,252,0,1,255,78,
0,84,113,96,128,0,209,69,128,21,87,240,0,7,253,72,1,81,221,66,0,3,69,117,0,
@@ -12283,16 +12823,90 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
157,85,98,112,80,137,241,66,128,0,166,213,33,53,24,66,121,106,0,
};
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = {
-40,102,117,110,99,116,105,111,110,40,100,44,97,41,123,102,117,110,99,116,
-105,111,110,32,98,40,97,44,98,44,99,41,123,79,98,106,101,99,116,46,100,101,
-102,105,110,101,80,114,111,112,101,114,116,121,40,97,44,98,44,123,118,97,
-108,117,101,58,99,44,119,114,105,116,97,98,108,101,58,33,48,44,101,110,117,
-109,101,114,97,98,108,101,58,33,49,44,99,111,110,102,105,103,117,114,97,98,
-108,101,58,33,48,125,41,125,98,40,97,46,76,111,103,103,101,114,44,34,99,
-108,111,103,34,44,110,101,119,32,97,46,76,111,103,103,101,114,40,34,67,34,
-41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,123,125,41,
-125,41,40,116,104,105,115,44,68,117,107,116,97,112,101,41,59,10,0,
+DUK_INTERNAL const duk_uint8_t duk_initjs_data[1757] = {
+47,42,10,32,42,32,32,73,110,105,116,32,99,111,100,101,32,102,111,114,32,
+108,101,103,97,99,121,32,99,111,109,112,97,116,105,98,105,108,105,116,121,
+46,10,32,42,10,32,42,32,32,67,111,109,112,97,116,105,98,105,108,105,116,
+121,32,112,114,111,112,101,114,116,105,101,115,32,47,32,119,114,97,112,112,
+101,114,32,102,117,110,99,116,105,111,110,115,32,104,101,114,101,32,97,108,
+108,111,119,32,68,117,107,116,97,112,101,32,116,111,32,114,101,109,97,105,
+110,10,32,42,32,32,99,111,109,112,97,116,105,98,108,101,32,102,111,114,32,
+117,115,101,114,32,99,111,100,101,32,119,104,101,110,32,99,111,114,101,32,
+102,101,97,116,117,114,101,115,32,97,114,101,32,99,104,97,110,103,101,100,
+44,32,119,105,116,104,111,117,116,32,98,117,114,100,101,110,105,110,103,10,
+32,42,32,32,116,104,101,32,109,97,105,110,32,67,32,99,111,100,101,32,119,
+105,116,104,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32,115,116,
+117,102,102,46,10,32,42,10,32,42,32,32,84,104,105,115,32,102,105,108,101,
+32,105,115,32,109,105,110,105,102,105,101,100,32,119,105,116,104,32,85,103,
+108,105,102,121,74,83,32,111,114,32,116,104,101,32,99,108,111,115,117,114,
+101,32,99,111,109,112,105,108,101,114,46,32,32,66,111,116,104,32,119,105,
+108,108,10,32,42,32,32,114,101,110,97,109,101,32,118,97,114,105,97,98,108,
+101,115,44,32,114,101,109,111,118,101,32,99,111,109,109,101,110,116,115,44,
+32,97,110,100,32,97,114,101,32,99,108,101,118,101,114,32,101,110,111,117,
+103,104,32,116,111,32,100,114,111,112,32,97,110,121,10,32,42,32,32,34,105,
+102,32,40,102,97,108,115,101,41,32,123,32,46,46,46,32,125,34,32,98,108,111,
+99,107,115,32,97,108,116,111,103,101,116,104,101,114,44,32,115,111,32,116,
+104,97,116,39,115,32,97,110,32,101,102,102,101,99,116,105,118,101,32,119,
+97,121,32,116,111,10,32,42,32,32,100,105,115,97,98,108,101,32,99,117,114,
+114,101,110,116,108,121,32,117,110,110,101,101,100,101,100,32,99,111,100,
+101,46,10,32,42,47,10,10,40,102,117,110,99,116,105,111,110,40,71,44,32,68,
+41,32,123,10,32,32,32,32,39,117,115,101,32,115,116,114,105,99,116,39,59,10,
+10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,101,102,40,111,98,106,
+101,99,116,44,32,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,
+32,32,32,32,32,32,32,79,98,106,101,99,116,46,100,101,102,105,110,101,80,
+114,111,112,101,114,116,121,40,111,98,106,101,99,116,44,32,110,97,109,101,
+44,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,118,97,108,117,101,58,32,
+118,97,108,117,101,44,10,32,32,32,32,32,32,32,32,32,32,32,32,119,114,105,
+116,97,98,108,101,58,32,116,114,117,101,44,10,32,32,32,32,32,32,32,32,32,
+32,32,32,101,110,117,109,101,114,97,98,108,101,58,32,102,97,108,115,101,44,
+10,32,32,32,32,32,32,32,32,32,32,32,32,99,111,110,102,105,103,117,114,97,
+98,108,101,58,32,116,114,117,101,10,32,32,32,32,32,32,32,32,125,41,59,10,
+32,32,32,32,125,10,10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,
+101,102,68,40,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,32,
+32,32,32,32,32,32,100,101,102,40,68,44,32,110,97,109,101,44,32,118,97,108,
+117,101,41,59,10,32,32,32,32,125,10,10,32,32,32,32,47,47,32,67,111,109,112,
+97,116,105,98,105,108,105,116,121,32,102,111,114,32,39,99,111,110,115,111,
+108,101,46,108,111,103,39,46,10,32,32,32,32,105,102,32,40,102,97,108,115,
+101,41,32,123,10,32,32,32,32,32,32,32,32,99,111,110,115,111,108,101,32,61,
+32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,108,111,103,58,32,102,117,
+110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,112,114,105,110,116,40,65,114,114,97,121,46,112,114,111,116,
+111,116,121,112,101,46,106,111,105,110,46,99,97,108,108,40,97,114,103,117,
+109,101,110,116,115,44,32,39,32,39,41,41,59,10,32,32,32,32,32,32,32,32,32,
+32,32,32,125,10,32,32,32,32,32,32,32,32,125,59,10,32,32,32,32,125,10,10,32,
+32,32,32,47,47,32,68,117,107,116,97,112,101,46,108,105,110,101,40,41,32,
+119,97,115,32,114,101,109,111,118,101,100,32,105,110,32,68,117,107,116,97,
+112,101,32,48,46,49,49,46,48,44,32,104,101,114,101,39,115,32,97,110,32,101,
+120,97,109,112,108,101,10,32,32,32,32,47,47,32,114,101,112,108,97,99,101,
+109,101,110,116,32,117,115,101,114,32,99,111,100,101,32,99,111,117,108,100,
+32,117,115,101,46,10,32,32,32,32,105,102,32,40,102,97,108,115,101,41,32,
+123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,108,105,110,101,
+39,44,32,102,117,110,99,116,105,111,110,32,40,41,32,123,10,32,32,32,32,32,
+32,32,32,32,32,32,32,39,117,115,101,32,100,117,107,32,110,111,116,97,105,
+108,39,59,10,10,32,32,32,32,32,32,32,32,32,32,32,32,47,42,32,84,97,105,108,
+32,99,97,108,108,115,32,97,114,101,32,112,114,101,118,101,110,116,101,100,
+32,116,111,32,101,110,115,117,114,101,32,99,97,108,108,105,110,103,32,97,
+99,116,105,118,97,116,105,111,110,32,101,120,105,115,116,115,46,10,32,32,
+32,32,32,32,32,32,32,32,32,32,32,42,32,67,97,108,108,32,115,116,97,99,107,
+32,105,110,100,105,99,101,115,58,32,45,49,32,61,32,68,117,107,116,97,112,
+101,46,97,99,116,44,32,45,50,32,61,32,103,101,116,67,117,114,114,101,110,
+116,76,105,110,101,44,32,45,51,32,61,32,99,97,108,108,101,114,10,32,32,32,
+32,32,32,32,32,32,32,32,32,32,42,47,10,10,32,32,32,32,32,32,32,32,32,32,32,
+32,114,101,116,117,114,110,32,40,68,117,107,116,97,112,101,46,97,99,116,40,
+45,51,41,32,124,124,32,123,125,41,46,108,105,110,101,78,117,109,98,101,114,
+59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,10,10,32,32,32,
+32,47,47,32,76,111,103,103,101,114,32,111,98,106,101,99,116,32,102,111,114,
+32,67,32,99,111,100,101,32,112,114,111,118,105,100,101,100,32,98,121,32,
+105,110,105,116,32,99,111,100,101,32,110,111,119,46,10,32,32,32,32,105,102,
+32,40,116,114,117,101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,
+68,46,76,111,103,103,101,114,44,32,39,99,108,111,103,39,44,32,110,101,119,
+32,68,46,76,111,103,103,101,114,40,39,67,39,41,41,59,10,32,32,32,32,125,10,
+10,32,32,32,32,47,47,32,84,114,97,99,107,105,110,103,32,116,97,98,108,101,
+32,102,111,114,32,67,111,109,109,111,110,74,83,32,109,111,100,117,108,101,
+32,108,111,97,100,105,110,103,46,10,32,32,32,32,105,102,32,40,116,114,117,
+101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,109,
+111,100,76,111,97,100,101,100,39,44,32,123,125,41,59,10,32,32,32,32,125,10,
+125,41,40,116,104,105,115,44,32,68,117,107,116,97,112,101,41,59,10,0,
};
#endif /* DUK_USE_BUILTIN_INITJS */
#elif defined(DUK_USE_DOUBLE_ME)
@@ -12637,7 +13251,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
156,80,0,70,82,113,64,1,89,41,197,0,6,100,39,20,0,29,142,156,80,0,134,50,
98,243,21,53,121,136,160,144,0,22,26,120,24,73,197,0,9,96,167,20,0,41,128,
156,80,0,181,250,113,64,3,1,255,254,0,81,20,100,47,145,216,23,255,240,0,11,
-255,248,0,3,255,252,81,252,8,1,220,68,0,0,0,0,0,129,167,1,26,144,9,165,0,
+255,248,0,3,255,252,81,252,8,4,252,68,0,0,0,0,0,129,167,1,26,144,9,165,0,
26,177,199,197,132,30,147,16,120,86,65,217,80,240,232,164,120,114,80,60,52,
39,32,84,223,192,15,59,30,129,156,115,6,81,160,7,253,40,0,5,81,252,0,1,255,
78,0,84,113,96,128,0,209,69,128,21,87,240,0,7,253,72,1,81,221,66,0,3,69,
@@ -12669,16 +13283,90 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1952] = {
106,0,
};
#ifdef DUK_USE_BUILTIN_INITJS
-DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = {
-40,102,117,110,99,116,105,111,110,40,100,44,97,41,123,102,117,110,99,116,
-105,111,110,32,98,40,97,44,98,44,99,41,123,79,98,106,101,99,116,46,100,101,
-102,105,110,101,80,114,111,112,101,114,116,121,40,97,44,98,44,123,118,97,
-108,117,101,58,99,44,119,114,105,116,97,98,108,101,58,33,48,44,101,110,117,
-109,101,114,97,98,108,101,58,33,49,44,99,111,110,102,105,103,117,114,97,98,
-108,101,58,33,48,125,41,125,98,40,97,46,76,111,103,103,101,114,44,34,99,
-108,111,103,34,44,110,101,119,32,97,46,76,111,103,103,101,114,40,34,67,34,
-41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,123,125,41,
-125,41,40,116,104,105,115,44,68,117,107,116,97,112,101,41,59,10,0,
+DUK_INTERNAL const duk_uint8_t duk_initjs_data[1757] = {
+47,42,10,32,42,32,32,73,110,105,116,32,99,111,100,101,32,102,111,114,32,
+108,101,103,97,99,121,32,99,111,109,112,97,116,105,98,105,108,105,116,121,
+46,10,32,42,10,32,42,32,32,67,111,109,112,97,116,105,98,105,108,105,116,
+121,32,112,114,111,112,101,114,116,105,101,115,32,47,32,119,114,97,112,112,
+101,114,32,102,117,110,99,116,105,111,110,115,32,104,101,114,101,32,97,108,
+108,111,119,32,68,117,107,116,97,112,101,32,116,111,32,114,101,109,97,105,
+110,10,32,42,32,32,99,111,109,112,97,116,105,98,108,101,32,102,111,114,32,
+117,115,101,114,32,99,111,100,101,32,119,104,101,110,32,99,111,114,101,32,
+102,101,97,116,117,114,101,115,32,97,114,101,32,99,104,97,110,103,101,100,
+44,32,119,105,116,104,111,117,116,32,98,117,114,100,101,110,105,110,103,10,
+32,42,32,32,116,104,101,32,109,97,105,110,32,67,32,99,111,100,101,32,119,
+105,116,104,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32,115,116,
+117,102,102,46,10,32,42,10,32,42,32,32,84,104,105,115,32,102,105,108,101,
+32,105,115,32,109,105,110,105,102,105,101,100,32,119,105,116,104,32,85,103,
+108,105,102,121,74,83,32,111,114,32,116,104,101,32,99,108,111,115,117,114,
+101,32,99,111,109,112,105,108,101,114,46,32,32,66,111,116,104,32,119,105,
+108,108,10,32,42,32,32,114,101,110,97,109,101,32,118,97,114,105,97,98,108,
+101,115,44,32,114,101,109,111,118,101,32,99,111,109,109,101,110,116,115,44,
+32,97,110,100,32,97,114,101,32,99,108,101,118,101,114,32,101,110,111,117,
+103,104,32,116,111,32,100,114,111,112,32,97,110,121,10,32,42,32,32,34,105,
+102,32,40,102,97,108,115,101,41,32,123,32,46,46,46,32,125,34,32,98,108,111,
+99,107,115,32,97,108,116,111,103,101,116,104,101,114,44,32,115,111,32,116,
+104,97,116,39,115,32,97,110,32,101,102,102,101,99,116,105,118,101,32,119,
+97,121,32,116,111,10,32,42,32,32,100,105,115,97,98,108,101,32,99,117,114,
+114,101,110,116,108,121,32,117,110,110,101,101,100,101,100,32,99,111,100,
+101,46,10,32,42,47,10,10,40,102,117,110,99,116,105,111,110,40,71,44,32,68,
+41,32,123,10,32,32,32,32,39,117,115,101,32,115,116,114,105,99,116,39,59,10,
+10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,101,102,40,111,98,106,
+101,99,116,44,32,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,
+32,32,32,32,32,32,32,79,98,106,101,99,116,46,100,101,102,105,110,101,80,
+114,111,112,101,114,116,121,40,111,98,106,101,99,116,44,32,110,97,109,101,
+44,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,118,97,108,117,101,58,32,
+118,97,108,117,101,44,10,32,32,32,32,32,32,32,32,32,32,32,32,119,114,105,
+116,97,98,108,101,58,32,116,114,117,101,44,10,32,32,32,32,32,32,32,32,32,
+32,32,32,101,110,117,109,101,114,97,98,108,101,58,32,102,97,108,115,101,44,
+10,32,32,32,32,32,32,32,32,32,32,32,32,99,111,110,102,105,103,117,114,97,
+98,108,101,58,32,116,114,117,101,10,32,32,32,32,32,32,32,32,125,41,59,10,
+32,32,32,32,125,10,10,32,32,32,32,102,117,110,99,116,105,111,110,32,100,
+101,102,68,40,110,97,109,101,44,32,118,97,108,117,101,41,32,123,10,32,32,
+32,32,32,32,32,32,100,101,102,40,68,44,32,110,97,109,101,44,32,118,97,108,
+117,101,41,59,10,32,32,32,32,125,10,10,32,32,32,32,47,47,32,67,111,109,112,
+97,116,105,98,105,108,105,116,121,32,102,111,114,32,39,99,111,110,115,111,
+108,101,46,108,111,103,39,46,10,32,32,32,32,105,102,32,40,102,97,108,115,
+101,41,32,123,10,32,32,32,32,32,32,32,32,99,111,110,115,111,108,101,32,61,
+32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,108,111,103,58,32,102,117,
+110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,112,114,105,110,116,40,65,114,114,97,121,46,112,114,111,116,
+111,116,121,112,101,46,106,111,105,110,46,99,97,108,108,40,97,114,103,117,
+109,101,110,116,115,44,32,39,32,39,41,41,59,10,32,32,32,32,32,32,32,32,32,
+32,32,32,125,10,32,32,32,32,32,32,32,32,125,59,10,32,32,32,32,125,10,10,32,
+32,32,32,47,47,32,68,117,107,116,97,112,101,46,108,105,110,101,40,41,32,
+119,97,115,32,114,101,109,111,118,101,100,32,105,110,32,68,117,107,116,97,
+112,101,32,48,46,49,49,46,48,44,32,104,101,114,101,39,115,32,97,110,32,101,
+120,97,109,112,108,101,10,32,32,32,32,47,47,32,114,101,112,108,97,99,101,
+109,101,110,116,32,117,115,101,114,32,99,111,100,101,32,99,111,117,108,100,
+32,117,115,101,46,10,32,32,32,32,105,102,32,40,102,97,108,115,101,41,32,
+123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,108,105,110,101,
+39,44,32,102,117,110,99,116,105,111,110,32,40,41,32,123,10,32,32,32,32,32,
+32,32,32,32,32,32,32,39,117,115,101,32,100,117,107,32,110,111,116,97,105,
+108,39,59,10,10,32,32,32,32,32,32,32,32,32,32,32,32,47,42,32,84,97,105,108,
+32,99,97,108,108,115,32,97,114,101,32,112,114,101,118,101,110,116,101,100,
+32,116,111,32,101,110,115,117,114,101,32,99,97,108,108,105,110,103,32,97,
+99,116,105,118,97,116,105,111,110,32,101,120,105,115,116,115,46,10,32,32,
+32,32,32,32,32,32,32,32,32,32,32,42,32,67,97,108,108,32,115,116,97,99,107,
+32,105,110,100,105,99,101,115,58,32,45,49,32,61,32,68,117,107,116,97,112,
+101,46,97,99,116,44,32,45,50,32,61,32,103,101,116,67,117,114,114,101,110,
+116,76,105,110,101,44,32,45,51,32,61,32,99,97,108,108,101,114,10,32,32,32,
+32,32,32,32,32,32,32,32,32,32,42,47,10,10,32,32,32,32,32,32,32,32,32,32,32,
+32,114,101,116,117,114,110,32,40,68,117,107,116,97,112,101,46,97,99,116,40,
+45,51,41,32,124,124,32,123,125,41,46,108,105,110,101,78,117,109,98,101,114,
+59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,10,10,32,32,32,
+32,47,47,32,76,111,103,103,101,114,32,111,98,106,101,99,116,32,102,111,114,
+32,67,32,99,111,100,101,32,112,114,111,118,105,100,101,100,32,98,121,32,
+105,110,105,116,32,99,111,100,101,32,110,111,119,46,10,32,32,32,32,105,102,
+32,40,116,114,117,101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,
+68,46,76,111,103,103,101,114,44,32,39,99,108,111,103,39,44,32,110,101,119,
+32,68,46,76,111,103,103,101,114,40,39,67,39,41,41,59,10,32,32,32,32,125,10,
+10,32,32,32,32,47,47,32,84,114,97,99,107,105,110,103,32,116,97,98,108,101,
+32,102,111,114,32,67,111,109,109,111,110,74,83,32,109,111,100,117,108,101,
+32,108,111,97,100,105,110,103,46,10,32,32,32,32,105,102,32,40,116,114,117,
+101,41,32,123,10,32,32,32,32,32,32,32,32,100,101,102,40,68,44,32,39,109,
+111,100,76,111,97,100,101,100,39,44,32,123,125,41,59,10,32,32,32,32,125,10,
+125,41,40,116,104,105,115,44,32,68,117,107,116,97,112,101,41,59,10,0,
};
#endif /* DUK_USE_BUILTIN_INITJS */
#else
@@ -13765,6 +14453,14 @@ DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread
*thr, duk_small_in
*/
DUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr,
duk_codepoint_t cp) {
+#if 1 /* FIXME */
+ /* Fast canonicalization lookup at the cost of 128kB footprint. */
+ DUK_ASSERT(cp >= 0);
+ if (DUK_LIKELY(cp < 0x10000L)) {
+ return (duk_codepoint_t) duk_unicode_re_canon_lookup[cp];
+ }
+ return cp;
+#else
duk_codepoint_t y;
y = duk__case_transform_helper(thr,
@@ -13782,6 +14478,7 @@ DUK_INTERNAL duk_codepoint_t
duk_unicode_re_canonicalize_char(duk_hthread *thr,
}
return y;
+#endif
}
/*
@@ -14185,8 +14882,8 @@ DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t
index, duk_size
h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index);
DUK_ASSERT(h != NULL);
- if (!DUK_HBUFFER_HAS_DYNAMIC(h)) {
- DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_BUFFER_NOT_DYNAMIC);
+ if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
+ DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE);
}
/* maximum size check is handled by callee */
@@ -14206,8 +14903,8 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t
index, duk_size_
h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index);
DUK_ASSERT(h != NULL);
- if (!DUK_HBUFFER_HAS_DYNAMIC(h)) {
- DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_BUFFER_NOT_DYNAMIC);
+ if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
+ DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE);
}
/* Forget the previous allocation, setting size to 0 and alloc to
@@ -14225,6 +14922,24 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t
index, duk_size_
return ptr;
}
+
+DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t index, void *ptr,
duk_size_t len) {
+ duk_hthread *thr = (duk_hthread *) ctx;
+ duk_hbuffer_external *h;
+
+ DUK_ASSERT(ctx != NULL);
+
+ h = (duk_hbuffer_external *) duk_require_hbuffer(ctx, index);
+ DUK_ASSERT(h != NULL);
+
+ if (!DUK_HBUFFER_HAS_EXTERNAL(h)) {
+ DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_WRONG_BUFFER_TYPE);
+ }
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));
+
+ DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);
+ DUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);
+}
#line 1 "duk_api_bytecode.c"
/*
* Bytecode dump/load
@@ -14608,7 +15323,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t
*p, duk_uint8_t
duk_uint8_t *fun_data;
duk_uint8_t *q;
duk_idx_t idx_base;
- duk_tval *tv;
+ duk_tval *tv1;
duk_uarridx_t arr_idx;
/* XXX: There's some overlap with duk_js_closure() here, but
@@ -14709,10 +15424,15 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t
*p, duk_uint8_t
break;
}
case DUK__SER_NUMBER: {
+ /* Important to do a fastint check so that constants are
+ * properly read back as fastints.
+ */
+ duk_tval tv_tmp;
duk_double_t val;
DUK__ASSERT_LEFT(8);
val = DUK_RAW_READ_DOUBLE_BE(p);
- duk_push_number(ctx, val);
+ DUK_TVAL_SET_NUMBER_CHKFAST(&tv_tmp, val);
+ duk_push_tval(ctx, &tv_tmp);
break;
}
default: {
@@ -14744,28 +15464,28 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t
*p, duk_uint8_t
DUK_HCOMPILEDFUNCTION_SET_DATA(thr->heap, h_fun, h_data);
DUK_HBUFFER_INCREF(thr, h_data);
- tv = duk_get_tval(ctx, idx_base + 2); /* may be NULL if no constants or inner funcs */
- DUK_ASSERT((count_const == 0 && count_funcs == 0) || tv != NULL);
+ tv1 = duk_get_tval(ctx, idx_base + 2); /* may be NULL if no constants or inner funcs
*/
+ DUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);
q = fun_data;
if (count_const > 0) {
- /* Explicit zero size check to avoid NULL 'tv'. */
- DUK_MEMCPY((void *) q, (const void *) tv, sizeof(duk_tval) * count_const);
+ /* Explicit zero size check to avoid NULL 'tv1'. */
+ DUK_MEMCPY((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);
for (n = count_const; n > 0; n--) {
DUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q); /* no side effects */
q += sizeof(duk_tval);
}
- tv += count_const;
+ tv1 += count_const;
}
DUK_HCOMPILEDFUNCTION_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);
for (n = count_funcs; n > 0; n--) {
duk_hobject *h_obj;
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
- h_obj = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));
+ h_obj = DUK_TVAL_GET_OBJECT(tv1);
DUK_ASSERT(h_obj != NULL);
- tv++;
+ tv1++;
DUK_HOBJECT_INCREF(thr, h_obj);
*((duk_hobject **) (void *) q) = h_obj;
@@ -15346,6 +16066,7 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) {
*/
#ifdef DUK_USE_AUGMENT_ERROR_CREATE
+ duk_hthread_sync_currpc(thr);
duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/);
#endif
@@ -15357,6 +16078,34 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_NOT_CONSTRUCTABLE);
}
+DUK_LOCAL duk_ret_t duk__pnew_helper(duk_context *ctx) {
+ duk_uint_t nargs;
+
+ nargs = duk_to_uint(ctx, -1);
+ duk_pop(ctx);
+
+ duk_new(ctx, nargs);
+ return 1;
+}
+
+DUK_EXTERNAL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs) {
+ duk_int_t rc;
+
+ DUK_ASSERT_CTX_VALID(ctx);
+
+ /* For now, just use duk_safe_call() to wrap duk_new(). We can't
+ * simply use a protected duk_handle_call() because there's post
+ * processing which might throw. It should be possible to ensure
+ * the post processing never throws (except in internal errors and
+ * out of memory etc which are always allowed) and then remove this
+ * wrapper.
+ */
+
+ duk_push_uint(ctx, nargs);
+ rc = duk_safe_call(ctx, duk__pnew_helper, nargs + 2 /*nargs*/, 1 /*nrets*/);
+ return rc;
+}
+
DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_activation *act;
@@ -15893,10 +16642,12 @@ DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char
*src_buffer, du
goto got_rc;
}
+ duk_push_global_object(ctx); /* explicit 'this' binding, see GH-164 */
+
if (flags & DUK_COMPILE_SAFE) {
- rc = duk_pcall(ctx, 0);
+ rc = duk_pcall_method(ctx, 0);
} else {
- duk_call(ctx, 0);
+ duk_call_method(ctx, 0);
rc = DUK_EXEC_SUCCESS;
}
@@ -16105,6 +16856,7 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
heap->dbg_processing = 0;
heap->dbg_paused = 1;
heap->dbg_state_dirty = 1;
+ heap->dbg_force_restart = 0;
heap->dbg_step_type = 0;
heap->dbg_step_thread = NULL;
heap->dbg_step_csindex = 0;
@@ -16284,6 +17036,7 @@ DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
*/
h_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];
+ DUK_UNREF(h_prev_glob);
thr->builtins[DUK_BIDX_GLOBAL] = h_glob;
DUK_HOBJECT_INCREF(thr, h_glob);
DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob); /* side effects, in theory (referenced
by global env) */
@@ -17110,6 +17863,7 @@ DUK_EXTERNAL duk_int_t duk_api_global_line = 0;
* Helpers
*/
+/* Check that there's room to push one value. */
#if defined(DUK_USE_VALSTACK_UNSAFE)
/* Faster but value stack overruns are memory unsafe. */
#define DUK__CHECK_SPACE() do { \
@@ -17185,9 +17939,9 @@ DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx,
duk_idx_t index, duk_b
if (require) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_NOT_NUMBER);
- } else {
- return 0;
+ /* not reachable */
}
+ return 0;
}
DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t index, duk_bool_t
require) {
@@ -17242,9 +17996,9 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx,
duk_idx_t index, duk
if (require) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_NOT_NUMBER);
- } else {
- return 0;
+ /* not reachable */
}
+ return 0;
}
/*
@@ -17258,7 +18012,8 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx,
duk_idx_t index, duk
DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_idx_t vs_size;
+ duk_uidx_t vs_size;
+ duk_uidx_t uindex;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
@@ -17270,117 +18025,110 @@ DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx,
duk_idx_t index) {
*/
/* Assume value stack sizes (in elements) fits into duk_idx_t. */
- vs_size = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- DUK_ASSERT(vs_size >= 0);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+ DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */
if (index < 0) {
- index = vs_size + index;
- if (DUK_UNLIKELY(index < 0)) {
- /* Also catches index == DUK_INVALID_INDEX: vs_size >= 0
- * so that vs_size + DUK_INVALID_INDEX cannot underflow
- * and will always be negative.
- */
- return DUK_INVALID_INDEX;
- }
+ uindex = vs_size + (duk_uidx_t) index;
} else {
/* since index non-negative */
DUK_ASSERT(index != DUK_INVALID_INDEX);
-
- if (DUK_UNLIKELY(index >= vs_size)) {
- return DUK_INVALID_INDEX;
- }
+ uindex = (duk_uidx_t) index;
}
- DUK_ASSERT(index >= 0);
- DUK_ASSERT(index < vs_size);
- return index;
+ /* DUK_INVALID_INDEX won't be accepted as a valid index. */
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);
+
+ if (DUK_LIKELY(uindex < vs_size)) {
+ return (duk_idx_t) uindex;
+ }
+ return DUK_INVALID_INDEX;
}
DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_idx_t vs_size;
+ duk_uidx_t vs_size;
+ duk_uidx_t uindex;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- vs_size = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- DUK_ASSERT(vs_size >= 0);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+ DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */
if (index < 0) {
- index = vs_size + index;
- if (DUK_UNLIKELY(index < 0)) {
- goto invalid_index;
- }
+ uindex = vs_size + (duk_uidx_t) index;
} else {
DUK_ASSERT(index != DUK_INVALID_INDEX);
- if (DUK_UNLIKELY(index >= vs_size)) {
- goto invalid_index;
- }
+ uindex = (duk_uidx_t) index;
}
- DUK_ASSERT(index >= 0);
- DUK_ASSERT(index < vs_size);
- return index;
+ /* DUK_INVALID_INDEX won't be accepted as a valid index. */
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);
- invalid_index:
+ if (DUK_LIKELY(uindex < vs_size)) {
+ return (duk_idx_t) uindex;
+ }
DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_INDEX);
return 0; /* unreachable */
}
DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_idx_t vs_size;
+ duk_uidx_t vs_size;
+ duk_uidx_t uindex;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- vs_size = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- DUK_ASSERT(vs_size >= 0);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+ DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */
if (index < 0) {
- index = vs_size + index;
- if (DUK_UNLIKELY(index < 0)) {
- return NULL;
- }
+ uindex = vs_size + (duk_uidx_t) index;
} else {
DUK_ASSERT(index != DUK_INVALID_INDEX);
- if (DUK_UNLIKELY(index >= vs_size)) {
- return NULL;
- }
+ uindex = (duk_uidx_t) index;
}
- DUK_ASSERT(index >= 0);
- DUK_ASSERT(index < vs_size);
- return thr->valstack_bottom + index;
+ /* DUK_INVALID_INDEX won't be accepted as a valid index. */
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);
+
+ if (DUK_LIKELY(uindex < vs_size)) {
+ return thr->valstack_bottom + uindex;
+ }
+ return NULL;
}
DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_idx_t vs_size;
+ duk_uidx_t vs_size;
+ duk_uidx_t uindex;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- vs_size = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- DUK_ASSERT(vs_size >= 0);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+ DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */
+ /* Use unsigned arithmetic to optimize comparison. */
if (index < 0) {
- index = vs_size + index;
- if (DUK_UNLIKELY(index < 0)) {
- goto invalid_index;
- }
+ uindex = vs_size + (duk_uidx_t) index;
} else {
DUK_ASSERT(index != DUK_INVALID_INDEX);
- if (DUK_UNLIKELY(index >= vs_size)) {
- goto invalid_index;
- }
+ uindex = (duk_uidx_t) index;
}
- DUK_ASSERT(index >= 0);
- DUK_ASSERT(index < vs_size);
- return thr->valstack_bottom + index;
+ /* DUK_INVALID_INDEX won't be accepted as a valid index. */
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);
- invalid_index:
+ if (DUK_LIKELY(uindex < vs_size)) {
+ return thr->valstack_bottom + uindex;
+ }
DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_INDEX);
return NULL;
}
@@ -17417,91 +18165,98 @@ DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx) {
return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
}
-/* set stack top within currently allocated range, but don't reallocate */
+/* Set stack top within currently allocated range, but don't reallocate.
+ * This is performance critical especially for call handling, so whenever
+ * changing, profile and look at generated code.
+ */
DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_idx_t vs_size;
- duk_idx_t vs_limit;
- duk_idx_t count;
- duk_tval tv_tmp;
+ duk_uidx_t vs_size;
+ duk_uidx_t vs_limit;
+ duk_uidx_t uindex;
duk_tval *tv;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- vs_size = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- vs_limit = (duk_idx_t) (thr->valstack_end - thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+ vs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom);
if (index < 0) {
/* Negative indices are always within allocated stack but
* must not go below zero index.
*/
- index = vs_size + index;
- if (index < 0) {
- /* Also catches index == DUK_INVALID_INDEX. */
- goto invalid_index;
- }
+ uindex = vs_size + (duk_uidx_t) index;
} else {
/* Positive index can be higher than valstack top but must
* not go above allocated stack (equality is OK).
*/
- if (index > vs_limit) {
- goto invalid_index;
- }
+ uindex = (duk_uidx_t) index;
}
- DUK_ASSERT(index >= 0);
- DUK_ASSERT(index <= vs_limit);
- if (index >= vs_size) {
- /* Stack size increases or stays the same. Fill the new
- * entries (if any) with undefined. No pointer stability
- * issues here so we can use a running pointer.
- */
+ /* DUK_INVALID_INDEX won't be accepted as a valid index. */
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);
+ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit);
- tv = thr->valstack_top;
- count = index - vs_size;
- DUK_ASSERT(count >= 0);
- while (count > 0) {
- /* no need to decref previous or new value */
+#if defined(DUK_USE_VALSTACK_UNSAFE)
+ DUK_ASSERT(uindex <= vs_limit);
+#else
+ if (DUK_UNLIKELY(uindex > vs_limit)) {
+ DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_INDEX);
+ return;
+ }
+#endif
+ DUK_ASSERT(uindex <= vs_limit);
+
+ /* Handle change in value stack top. Respect value stack
+ * initialization policy: 'undefined' above top. Note that
+ * DECREF may cause a side effect that reallocates valstack,
+ * so must relookup after DECREF.
+ */
+
+ if (uindex >= vs_size) {
+ /* Stack size increases or stays the same. */
+#if defined(DUK_USE_ASSERTIONS)
+ duk_uidx_t count;
+
+ count = uindex - vs_size;
+ while (count != 0) {
count--;
- DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(tv));
- DUK_TVAL_SET_UNDEFINED_ACTUAL(tv);
- tv++;
+ tv = thr->valstack_top + count;
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));
}
- thr->valstack_top = tv;
+#endif
+ thr->valstack_top = thr->valstack_bottom + uindex;
} else {
- /* Stack size decreases, DECREF entries which are above the
- * new top. Each DECREF potentially invalidates valstack
- * pointers, so don't hold on to pointers. The valstack top
- * must also be updated on every loop in case a GC is triggered.
- */
-
- /* XXX: Here it would be useful to have a DECREF macro which
- * doesn't need a NULL check, and does refzero queueing without
- * running the refzero algorithm. There would be no pointer
- * instability in this case, and code could be inlined. After
- * the loop, one call to refzero would be needed.
- */
+ /* Stack size decreases. */
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ duk_uidx_t count;
- count = vs_size - index;
+ count = vs_size - uindex;
DUK_ASSERT(count > 0);
-
while (count > 0) {
count--;
- tv = --thr->valstack_top; /* tv -> value just before prev top value */
+ tv = --thr->valstack_top; /* tv -> value just before prev top value; must
relookup */
DUK_ASSERT(tv >= thr->valstack_bottom);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
-
- /* XXX: fast primitive to set a bunch of values to UNDEFINED_UNUSED */
-
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
- }
- return;
+#else /* DUK_USE_REFERENCE_COUNTING */
+ duk_uidx_t count;
+ duk_tval *tv_end;
- invalid_index:
- DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_INDEX);
+ count = vs_size - uindex;
+ tv = thr->valstack_top;
+ tv_end = tv - count;
+ DUK_ASSERT(tv > tv_end);
+ do {
+ tv--;
+ DUK_TVAL_SET_UNDEFINED(tv);
+ } while (tv != tv_end);
+ thr->valstack_top = tv_end;
+#endif /* DUK_USE_REFERENCE_COUNTING */
+ }
}
DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx) {
@@ -17567,8 +18322,8 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx,
duk_size_t new_size)
duk_tval *old_valstack_post;
#endif
duk_tval *new_valstack;
- duk_tval *p;
duk_size_t new_alloc_size;
+ duk_tval *p;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(thr != NULL);
@@ -17591,7 +18346,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx,
duk_size_t new_size)
*
* Note: cannot use a plain DUK_REALLOC() because a mark-and-sweep may
* invalidate the original thr->valstack base pointer inside the realloc
- * process. See doc/memory-management.txt.
+ * process. See doc/memory-management.rst.
*/
new_alloc_size = sizeof(duk_tval) * new_size;
@@ -17619,7 +18374,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx,
duk_size_t new_size)
* because mark-and-sweep must adhere to a strict stack policy.
* In other words, logical bottom and top MUST NOT have changed.
* - All values above the top are unreachable but are initialized
- * to UNDEFINED_UNUSED, up to the post-realloc valstack_end.
+ * to UNDEFINED, up to the post-realloc valstack_end.
* - 'old_end_offset' must be computed after realloc to be correct.
*/
@@ -17633,6 +18388,9 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx,
duk_size_t new_size)
#endif
thr->valstack = new_valstack;
thr->valstack_end = new_valstack + new_size;
+#if !defined(DUK_USE_PREFER_SIZE)
+ thr->valstack_size = new_size;
+#endif
thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack +
old_bottom_offset);
thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack +
old_top_offset);
@@ -17663,23 +18421,23 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx,
duk_size_t new_size)
(void *) thr->valstack, (void *) thr->valstack_end,
(void *) thr->valstack_bottom, (void *) thr->valstack_top));
- /* init newly allocated slots (only) */
+ /* Init newly allocated slots (only). */
p = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + old_end_offset_post);
while (p < thr->valstack_end) {
- /* never executed if new size is smaller */
- DUK_TVAL_SET_UNDEFINED_UNUSED(p);
+ /* Never executed if new size is smaller. */
+ DUK_TVAL_SET_UNDEFINED(p);
p++;
}
- /* assertion check: we maintain elements above top in known state */
-#ifdef DUK_USE_ASSERTIONS
+ /* Assert for value stack initialization policy. */
+#if defined(DUK_USE_ASSERTIONS)
p = thr->valstack_top;
while (p < thr->valstack_end) {
- /* everything above old valstack top should be preinitialized now */
- DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(p));
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));
p++;
}
#endif
+
return 1;
}
@@ -17709,7 +18467,12 @@ duk_bool_t duk_valstack_resize_raw(duk_context *ctx,
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+#if defined(DUK_USE_PREFER_SIZE)
old_size = (duk_size_t) (thr->valstack_end - thr->valstack);
+#else
+ DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack) ==
thr->valstack_size);
+ old_size = thr->valstack_size;
+#endif
if (min_new_size <= old_size) {
is_shrink = 1;
@@ -17983,10 +18746,9 @@ DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t
to_index) {
/* For tv1 == tv2, both pointing to stack top, the end result
* is same as duk_pop(ctx).
*/
-
DUK_TVAL_SET_TVAL(&tv_tmp, tv2);
DUK_TVAL_SET_TVAL(tv2, tv1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv1);
+ DUK_TVAL_SET_UNDEFINED(tv1);
thr->valstack_top--;
DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
}
@@ -17995,7 +18757,6 @@ DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t from_index,
duk_idx_t to_
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv1;
duk_tval *tv2;
- duk_tval tv_tmp;
DUK_ASSERT_CTX_VALID(ctx);
DUK_UNREF(thr); /* w/o refcounting */
@@ -18006,11 +18767,7 @@ DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t
from_index, duk_idx_t to_
DUK_ASSERT(tv2 != NULL);
/* For tv1 == tv2, this is a no-op (no explicit check needed). */
-
- DUK_TVAL_SET_TVAL(&tv_tmp, tv2);
- DUK_TVAL_SET_TVAL(tv2, tv1);
- DUK_TVAL_INCREF(thr, tv2); /* no side effects */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1); /* side effects */
}
DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index) {
@@ -18045,7 +18802,7 @@ DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index) {
nbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p)); /* Note: 'q'
is top-1 */
DUK_MEMMOVE(p, p + 1, nbytes); /* zero size not an issue: pointers are valid */
- DUK_TVAL_SET_UNDEFINED_UNUSED(q);
+ DUK_TVAL_SET_UNDEFINED(q);
thr->valstack_top--;
#ifdef DUK_USE_REFERENCE_COUNTING
@@ -18106,24 +18863,22 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx,
duk_context *from_ctx,
to_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);
if (is_copy) {
- /* incref copies, keep originals */
+ /* Incref copies, keep originals. */
q = to_thr->valstack_top;
while (p < q) {
DUK_TVAL_INCREF(to_thr, p); /* no side effects */
p++;
}
} else {
- /* no net refcount change */
+ /* No net refcount change. */
p = from_thr->valstack_top;
q = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes);
from_thr->valstack_top = q;
- /* elements above stack top are kept UNUSED */
while (p > q) {
p--;
- DUK_TVAL_SET_UNDEFINED_UNUSED(p);
-
- /* XXX: fast primitive to set a bunch of values to UNDEFINED_UNUSED */
+ DUK_TVAL_SET_UNDEFINED(p);
+ /* XXX: fast primitive to set a bunch of values to UNDEFINED */
}
}
}
@@ -18790,6 +19545,7 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t
index) {
#endif
default:
/* number */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
return 0;
}
@@ -18880,31 +19636,25 @@ DUK_EXTERNAL void duk_to_defaultvalue(duk_context *ctx,
duk_idx_t index, duk_int
DUK_EXTERNAL void duk_to_undefined(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
DUK_ASSERT_CTX_VALID(ctx);
DUK_UNREF(thr);
tv = duk_require_tval(ctx, index);
DUK_ASSERT(tv != NULL);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_ACTUAL(tv); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
DUK_EXTERNAL void duk_to_null(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
DUK_ASSERT_CTX_VALID(ctx);
DUK_UNREF(thr);
tv = duk_require_tval(ctx, index);
DUK_ASSERT(tv != NULL);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NULL(tv); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NULL_UPDREF(thr, tv); /* side effects */
}
/* E5 Section 9.1 */
@@ -18926,7 +19676,6 @@ DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t
index, duk_int_t
DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_bool_t val;
DUK_ASSERT_CTX_VALID(ctx);
@@ -18942,16 +19691,13 @@ DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx,
duk_idx_t index) {
/* Note: no need to re-lookup tv, conversion is side effect free */
DUK_ASSERT(tv != NULL);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_BOOLEAN(tv, val); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val); /* side effects */
return val;
}
DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_double_t d;
DUK_ASSERT_CTX_VALID(ctx);
@@ -18963,9 +19709,7 @@ DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx,
duk_idx_t index) {
/* Note: need to re-lookup because ToNumber() may have side effects */
tv = duk_require_tval(ctx, index);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NUMBER(tv, d); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */
return d;
}
@@ -18978,7 +19722,6 @@ typedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr,
duk_tval *tv);
DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_context *ctx, duk_idx_t index,
duk__toint_coercer coerce_func) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_double_t d;
DUK_ASSERT_CTX_VALID(ctx);
@@ -18991,9 +19734,7 @@ DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_context *ctx,
duk_idx_t index
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
tv = duk_require_tval(ctx, index);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NUMBER(tv, d); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */
return d;
}
@@ -19018,7 +19759,6 @@ DUK_EXTERNAL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t
index) {
DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_int32_t ret;
DUK_ASSERT_CTX_VALID(ctx);
@@ -19030,14 +19770,10 @@ DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx,
duk_idx_t index) {
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
tv = duk_require_tval(ctx, index);
#if defined(DUK_USE_FASTINT)
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_FASTINT_I32(tv, ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_I32_UPDREF(thr, tv, ret); /* side effects */
return ret;
#else
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NUMBER(tv, (duk_double_t) ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, (duk_double_t) ret); /* side effects */
return ret;
#endif
}
@@ -19045,7 +19781,6 @@ DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t
index) {
DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_uint32_t ret;
DUK_ASSERT_CTX_VALID(ctx);
@@ -19057,14 +19792,10 @@ DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx,
duk_idx_t index) {
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
tv = duk_require_tval(ctx, index);
#if defined(DUK_USE_FASTINT)
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_FASTINT_U32(tv, ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_U32_UPDREF(thr, tv, ret); /* side effects */
return ret;
#else
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NUMBER(tv, (duk_double_t) ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, (duk_double_t) ret); /* side effects */
#endif
return ret;
}
@@ -19072,7 +19803,6 @@ DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx,
duk_idx_t index) {
DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv;
- duk_tval tv_tmp;
duk_uint16_t ret;
DUK_ASSERT_CTX_VALID(ctx);
@@ -19084,18 +19814,15 @@ DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_context *ctx,
duk_idx_t index) {
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
tv = duk_require_tval(ctx, index);
#if defined(DUK_USE_FASTINT)
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_FASTINT_U32(tv, ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_U32_UPDREF(thr, tv, ret); /* side effects */
return ret;
#else
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_NUMBER(tv, (duk_double_t) ret); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, (duk_double_t) ret); /* side effects */
#endif
return ret;
}
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Special coercion for Uint8ClampedArray. */
DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index) {
duk_double_t d;
@@ -19130,6 +19857,7 @@ DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx,
duk_idx_t index)
}
return ret;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
DUK_EXTERNAL const char *duk_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t
*out_len) {
DUK_ASSERT_CTX_VALID(ctx);
@@ -19171,10 +19899,20 @@ DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx,
duk_idx_t index,
;
}
DUK_ASSERT(duk_is_string(ctx, -1));
+ DUK_ASSERT(duk_get_string(ctx, -1) != NULL);
duk_replace(ctx, index);
- return duk_require_lstring(ctx, index, out_len);
+ return duk_get_lstring(ctx, index, out_len);
+}
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */
+DUK_EXTERNAL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t index) {
+ (void) duk_safe_to_string(ctx, index);
+ DUK_ASSERT(duk_is_string(ctx, index));
+ DUK_ASSERT(duk_get_hstring(ctx, index) != NULL);
+ return duk_get_hstring(ctx, index);
}
+#endif
/* XXX: other variants like uint, u32 etc */
DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index,
duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {
@@ -19318,6 +20056,7 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t
index) {
#endif
default: {
/* number */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
duk_push_tval(ctx, tv);
duk_numconv_stringify(ctx,
@@ -19358,7 +20097,9 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t
index, duk_size
h_buf = duk_get_hbuffer(ctx, index);
if (h_buf != NULL) {
/* Buffer is kept as is, with the fixed/dynamic nature of the
- * buffer only changed if requested.
+ * buffer only changed if requested. An external buffer
+ * is converted into a non-external dynamic buffer in a
+ * duk_to_dynamic_buffer() call.
*/
duk_uint_t tmp;
@@ -19366,7 +20107,8 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t
index, duk_size
src_size = DUK_HBUFFER_GET_SIZE(h_buf);
tmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);
- if (tmp == mode || mode == DUK_BUF_MODE_DONTCARE) {
+ if ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) ||
+ mode == DUK_BUF_MODE_DONTCARE) {
/* Note: src_data may be NULL if input is a zero-size
* dynamic buffer.
*/
@@ -19440,6 +20182,8 @@ DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t
index) {
#endif
default:
/* number */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
res = NULL;
break;
}
@@ -19497,11 +20241,11 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t
index) {
h_val = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h_val != NULL);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
- DUK_BIDX_BUFFER_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
+ DUK_BIDX_BUFFER_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE((duk_hobject *) h_bufobj));
DUK_ASSERT(DUK_HOBJECT_IS_BUFFEROBJECT((duk_hobject *) h_bufobj));
@@ -19575,6 +20319,8 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index)
{
case DUK_TAG_FASTINT:
#endif
default: {
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER);
proto = DUK_BIDX_NUMBER_PROTOTYPE;
@@ -19657,6 +20403,7 @@ DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t
index) {
#endif
default:
/* Note: number has no explicit tag (in 8-byte representation) */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
return DUK_TYPE_NUMBER;
}
@@ -19700,6 +20447,7 @@ DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_context *ctx,
duk_idx_t index) {
#endif
default:
/* Note: number has no explicit tag (in 8-byte representation) */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
return DUK_TYPE_MASK_NUMBER;
}
@@ -19874,7 +20622,7 @@ DUK_EXTERNAL duk_bool_t duk_is_callable(duk_context *ctx,
duk_idx_t index) {
return duk_is_function(ctx, index);
}
-DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t index) {
+DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t index) {
duk_tval *tv;
DUK_ASSERT_CTX_VALID(ctx);
@@ -19883,12 +20631,12 @@ DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx,
duk_idx_t index)
if (tv && DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL);
- return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 1 : 0);
+ return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);
}
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t index) {
+DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t index) {
duk_tval *tv;
DUK_ASSERT_CTX_VALID(ctx);
@@ -19897,16 +20645,23 @@ DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx,
duk_idx_t index) {
if (tv && DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL);
- return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);
+ return (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);
}
return 0;
}
-/* XXX: make macro in API */
-DUK_EXTERNAL duk_bool_t duk_is_primitive(duk_context *ctx, duk_idx_t index) {
+DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t index) {
+ duk_tval *tv;
+
DUK_ASSERT_CTX_VALID(ctx);
- return !duk_is_object(ctx, index);
+ tv = duk_get_tval(ctx, index);
+ if (tv && DUK_TVAL_IS_BUFFER(tv)) {
+ duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
+ DUK_ASSERT(h != NULL);
+ return (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);
+ }
+ return 0;
}
DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t index) {
@@ -19968,29 +20723,18 @@ DUK_INTERNAL void duk_push_tval(duk_context *ctx, duk_tval *tv)
{
DUK_TVAL_INCREF(thr, tv); /* no side effects */
}
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-/* Right now only needed by the debugger. */
-DUK_INTERNAL void duk_push_unused(duk_context *ctx) {
- duk_hthread *thr;
- duk_tval *tv_slot;
-
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK__CHECK_SPACE();
- tv_slot = thr->valstack_top++;
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv_slot);
-}
-#endif
-
DUK_EXTERNAL void duk_push_undefined(duk_context *ctx) {
duk_hthread *thr;
- duk_tval *tv_slot;
DUK_ASSERT_CTX_VALID(ctx);
thr = (duk_hthread *) ctx;
DUK__CHECK_SPACE();
- tv_slot = thr->valstack_top++;
- DUK_TVAL_SET_UNDEFINED_ACTUAL(tv_slot);
+
+ /* Because value stack init policy is 'undefined above top',
+ * we don't need to write, just assert.
+ */
+ thr->valstack_top++;
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));
}
DUK_EXTERNAL void duk_push_null(duk_context *ctx) {
@@ -20263,46 +21007,39 @@ DUK_EXTERNAL void duk_push_pointer(duk_context *ctx, void *val)
{
DUK_TVAL_SET_POINTER(tv_slot, val);
}
-#define DUK__PUSH_THIS_FLAG_CHECK_COERC (1 << 0)
-#define DUK__PUSH_THIS_FLAG_TO_OBJECT (1 << 1)
-#define DUK__PUSH_THIS_FLAG_TO_STRING (1 << 2)
-
-DUK_LOCAL void duk__push_this_helper(duk_context *ctx, duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL void duk__push_this_helper(duk_context *ctx, duk_small_uint_t
check_object_coercible) {
+ duk_hthread *thr;
+ duk_tval *tv_slot;
- DUK_ASSERT(thr != NULL);
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
+ thr = (duk_hthread *) ctx;
DUK_ASSERT(thr->callstack_top <= thr->callstack_size);
+ DUK__CHECK_SPACE();
- if (thr->callstack_top == 0) {
- if (flags & DUK__PUSH_THIS_FLAG_CHECK_COERC) {
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* because of valstack init
policy */
+ tv_slot = thr->valstack_top++;
+
+ if (DUK_UNLIKELY(thr->callstack_top == 0)) {
+ if (check_object_coercible) {
goto type_error;
}
- duk_push_undefined(ctx);
+ /* 'undefined' already on stack top */
} else {
- duk_tval tv_tmp;
duk_tval *tv;
/* 'this' binding is just before current activation's bottom */
DUK_ASSERT(thr->valstack_bottom > thr->valstack);
tv = thr->valstack_bottom - 1;
- if (flags & DUK__PUSH_THIS_FLAG_CHECK_COERC) {
- if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {
- goto type_error;
- }
+ if (check_object_coercible &&
+ (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) {
+ /* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */
+ goto type_error;
}
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- duk_push_tval(ctx, &tv_tmp);
- }
-
- if (flags & DUK__PUSH_THIS_FLAG_TO_OBJECT) {
- duk_to_object(ctx, -1);
- } else if (flags & DUK__PUSH_THIS_FLAG_TO_STRING) {
- duk_to_string(ctx, -1);
+ DUK_TVAL_SET_TVAL(tv_slot, tv);
+ DUK_TVAL_INCREF(thr, tv);
}
-
return;
type_error:
@@ -20312,13 +21049,13 @@ DUK_LOCAL void duk__push_this_helper(duk_context *ctx,
duk_small_uint_t flags) {
DUK_EXTERNAL void duk_push_this(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
- duk__push_this_helper(ctx, 0 /*flags*/);
+ duk__push_this_helper(ctx, 0 /*check_object_coercible*/);
}
DUK_INTERNAL void duk_push_this_check_object_coercible(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
- duk__push_this_helper(ctx, DUK__PUSH_THIS_FLAG_CHECK_COERC /*flags*/);
+ duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
}
DUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_context *ctx) {
@@ -20326,8 +21063,8 @@ DUK_INTERNAL duk_hobject
*duk_push_this_coercible_to_object(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
- duk__push_this_helper(ctx, DUK__PUSH_THIS_FLAG_CHECK_COERC |
- DUK__PUSH_THIS_FLAG_TO_OBJECT /*flags*/);
+ duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
+ duk_to_object(ctx, -1);
h = duk_get_hobject(ctx, -1);
DUK_ASSERT(h != NULL);
return h;
@@ -20338,8 +21075,8 @@ DUK_INTERNAL duk_hstring
*duk_push_this_coercible_to_string(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
- duk__push_this_helper(ctx, DUK__PUSH_THIS_FLAG_CHECK_COERC |
- DUK__PUSH_THIS_FLAG_TO_STRING /*flags*/);
+ duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
+ duk_to_string(ctx, -1);
h = duk_get_hstring(ctx, -1);
DUK_ASSERT(h != NULL);
return h;
@@ -20869,7 +21606,7 @@ DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_context *ctx,
duk_c_function fun
return 0; /* not reached */
}
-DUK_INTERNAL duk_hbufferobject *duk_push_bufferobject(duk_context *ctx, duk_uint_t
hobject_flags_and_class, duk_small_int_t prototype_bidx) {
+DUK_INTERNAL duk_hbufferobject *duk_push_bufferobject_raw(duk_context *ctx, duk_uint_t
hobject_flags_and_class, duk_small_int_t prototype_bidx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hbufferobject *obj;
duk_tval *tv_slot;
@@ -20898,6 +21635,134 @@ DUK_INTERNAL duk_hbufferobject
*duk_push_bufferobject(duk_context *ctx, duk_uint
return obj;
}
+/* XXX: There's quite a bit of overlap with buffer creation handling in
+ * duk_bi_buffer.c. Look for overlap and refactor.
+ */
+#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,isview) \
+ (((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) |
((elemshift) << 4) | (isview))
+
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+static const duk_uint32_t duk__bufobj_flags_lookup[] = {
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_BUFFER, DUK_BIDX_BUFFER_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 0), /* DUK_BUFOBJ_DUKTAPE_BUFFER */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_BUFFER, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 0), /* DUK_BUFOBJ_NODEJS_BUFFER */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER, DUK_BIDX_ARRAYBUFFER_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 0), /* DUK_BUFOBJ_ARRAYBUFFER */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW, DUK_BIDX_DATAVIEW_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 1), /* DUK_BUFOBJ_DATAVIEW */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY, DUK_BIDX_INT8ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_INT8, 0, 1), /* DUK_BUFOBJ_INT8ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY, DUK_BIDX_UINT8ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 1), /* DUK_BUFOBJ_UINT8ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY,
DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED, 0, 1), /*
DUK_BUFOBJ_UINT8CLAMPEDARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY, DUK_BIDX_INT16ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_INT16, 1, 1), /* DUK_BUFOBJ_INT16ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY, DUK_BIDX_UINT16ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT16, 1, 1), /* DUK_BUFOBJ_UINT16ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY, DUK_BIDX_INT32ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_INT32, 2, 1), /* DUK_BUFOBJ_INT32ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY, DUK_BIDX_UINT32ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT32, 2, 1), /* DUK_BUFOBJ_UINT32ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY, DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_FLOAT32, 2, 1), /* DUK_BUFOBJ_FLOAT32ARRAY */
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY, DUK_BIDX_FLOAT64ARRAY_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_FLOAT64, 3, 1) /* DUK_BUFOBJ_FLOAT64ARRAY */
+};
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+/* Only allow Duktape.Buffer when support disabled. */
+static const duk_uint32_t duk__bufobj_flags_lookup[] = {
+ DUK__PACK_ARGS(DUK_HOBJECT_CLASS_BUFFER, DUK_BIDX_BUFFER_PROTOTYPE,
DUK_HBUFFEROBJECT_ELEM_UINT8, 0, 0) /* DUK_BUFOBJ_DUKTAPE_BUFFER */
+};
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#undef DUK__PACK_ARGS
+
+DUK_EXTERNAL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer,
duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {
+ duk_hthread *thr;
+ duk_hbufferobject *h_bufobj;
+ duk_hbuffer *h_val;
+ duk_uint32_t tmp;
+ duk_uint_t classnum;
+ duk_uint_t protobidx;
+ duk_uint_t lookupidx;
+ duk_uint_t uint_offset, uint_length, uint_added;
+
+ DUK_ASSERT_CTX_VALID(ctx);
+ thr = (duk_hthread *) ctx;
+ DUK_UNREF(thr);
+
+ /* The underlying types for offset/length in duk_hbufferobject is
+ * duk_uint_t; make sure argument values fit and that offset + length
+ * does not wrap.
+ */
+ uint_offset = (duk_uint_t) byte_offset;
+ uint_length = (duk_uint_t) byte_length;
+ if (sizeof(duk_size_t) != sizeof(duk_uint_t)) {
+ if ((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)
{
+ goto range_error;
+ }
+ }
+ uint_added = uint_offset + uint_length;
+ if (uint_added < uint_offset) {
+ goto range_error;
+ }
+ DUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);
+
+ DUK_ASSERT_DISABLE(flags >= 0); /* flags is unsigned */
+ lookupidx = flags & 0x0f; /* 4 low bits */
+ if (lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t)) {
+ goto arg_error;
+ }
+ tmp = duk__bufobj_flags_lookup[lookupidx];
+ classnum = tmp >> 24;
+ protobidx = (tmp >> 16) & 0xff;
+
+ h_val = duk_require_hbuffer(ctx, idx_buffer);
+ DUK_ASSERT(h_val != NULL);
+
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+ DUK_HOBJECT_CLASS_AS_FLAGS(classnum),
+ protobidx);
+ DUK_ASSERT(h_bufobj != NULL);
+
+ h_bufobj->buf = h_val;
+ DUK_HBUFFER_INCREF(thr, h_val);
+ h_bufobj->offset = uint_offset;
+ h_bufobj->length = uint_length;
+ h_bufobj->shift = (tmp >> 4) & 0x0f;
+ h_bufobj->elem_type = (tmp >> 8) & 0xff;
+ h_bufobj->is_view = tmp & 0x0f;
+ DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
+
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+ /* TypedArray views need an automatic ArrayBuffer which must be
+ * provided as .buffer property of the view. Just create a new
+ * ArrayBuffer sharing the same underlying buffer.
+ */
+ if (flags & DUK_BUFOBJ_CREATE_ARRBUF) {
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
+ DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
+
+ DUK_ASSERT(h_bufobj != NULL);
+
+ h_bufobj->buf = h_val;
+ DUK_HBUFFER_INCREF(thr, h_val);
+ h_bufobj->offset = uint_offset;
+ h_bufobj->length = uint_length;
+ DUK_ASSERT(h_bufobj->shift == 0);
+ h_bufobj->elem_type = DUK_HBUFFEROBJECT_ELEM_UINT8;
+ DUK_ASSERT(h_bufobj->is_view == 0);
+ DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
+
+ duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LC_BUFFER, DUK_PROPDESC_FLAGS_NONE);
+ duk_compact(ctx, -1);
+ }
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+
+ return;
+
+ range_error:
+ DUK_ERROR(thr, DUK_ERR_RANGE_ERROR, DUK_STR_INVALID_CALL_ARGS);
+ return; /* not reached */
+
+ arg_error:
+ DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_CALL_ARGS);
+ return; /* not reached */
+}
+
DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t
err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_idx_t ret;
@@ -20988,6 +21853,7 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx,
duk_size_t size, duk_sm
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv_slot;
duk_hbuffer *h;
+ void *buf_data;
DUK_ASSERT_CTX_VALID(ctx);
@@ -21001,7 +21867,7 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx,
duk_size_t size, duk_sm
DUK_ERROR(thr, DUK_ERR_RANGE_ERROR, DUK_STR_BUFFER_TOO_LONG);
}
- h = duk_hbuffer_alloc(thr->heap, size, flags);
+ h = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);
if (!h) {
DUK_ERROR(thr, DUK_ERR_ALLOC_ERROR, DUK_STR_ALLOC_FAILED);
}
@@ -21011,7 +21877,7 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx,
duk_size_t size, duk_sm
DUK_HBUFFER_INCREF(thr, h);
thr->valstack_top++;
- return DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
+ return (void *) buf_data;
}
DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr) {
@@ -21098,16 +21964,17 @@ DUK_INTERNAL void duk_push_hobject_bidx(duk_context *ctx,
duk_small_int_t builti
DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count) {
duk_hthread *thr = (duk_hthread *) ctx;
+ duk_tval *tv;
DUK_ASSERT_CTX_VALID(ctx);
- if (count < 0) {
+ if (DUK_UNLIKELY(count < 0)) {
DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_INVALID_COUNT);
return;
}
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- if ((duk_size_t) (thr->valstack_top - thr->valstack_bottom) < (duk_size_t)
count) {
+ if (DUK_UNLIKELY((duk_size_t) (thr->valstack_top - thr->valstack_bottom) <
(duk_size_t) count)) {
DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_POP_TOO_MANY);
}
@@ -21121,36 +21988,58 @@ DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count)
{
* instability), inline code.
*/
-#ifdef DUK_USE_REFERENCE_COUNTING
- while (count > 0) {
- duk_tval tv_tmp;
- duk_tval *tv;
+ /* XXX: optimize loops */
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ while (count > 0) {
+ count--;
tv = --thr->valstack_top; /* tv points to element just below prev top */
DUK_ASSERT(tv >= thr->valstack_bottom);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
- count--;
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
#else
+ tv = thr->valstack_top;
while (count > 0) {
- duk_tval *tv;
-
- tv = --thr->valstack_top;
- DUK_ASSERT(tv >= thr->valstack_bottom);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
count--;
+ tv--;
+ DUK_ASSERT(tv >= thr->valstack_bottom);
+ DUK_TVAL_SET_UNDEFINED(tv);
}
+ thr->valstack_top = tv;
#endif
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
}
+/* Popping one element is called so often that when footprint is not an issue,
+ * compile a specialized function for it.
+ */
+#if defined(DUK_USE_PREFER_SIZE)
DUK_EXTERNAL void duk_pop(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
duk_pop_n(ctx, 1);
}
+#else
+DUK_EXTERNAL void duk_pop(duk_context *ctx) {
+ duk_hthread *thr = (duk_hthread *) ctx;
+ duk_tval *tv;
+ DUK_ASSERT_CTX_VALID(ctx);
+
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {
+ DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_POP_TOO_MANY);
+ }
+
+ tv = --thr->valstack_top; /* tv points to element just below prev top */
+ DUK_ASSERT(tv >= thr->valstack_bottom);
+#ifdef DUK_USE_REFERENCE_COUNTING
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
+#else
+ DUK_TVAL_SET_UNDEFINED(tv);
+#endif
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+}
+#endif /* !DUK_USE_PREFER_SIZE */
DUK_EXTERNAL void duk_pop_2(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
@@ -21182,6 +22071,12 @@ DUK_EXTERNAL void duk_throw(duk_context *ctx) {
* just before an error is thrown.
*/
+ /* Sync so that augmentation sees up-to-date activations, NULL
+ * thr->ptr_curr_pc so that it's not used if side effects occur
+ * in augmentation or longjmp handling.
+ */
+ duk_hthread_sync_and_null_currpc(thr);
+
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (before throw augment)",
(duk_tval *) duk_get_tval(ctx, -1)));
duk_err_augment_error_throw(thr);
@@ -21423,7 +22318,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx,
duk_idx_t count_in,
h = duk_to_hstring(ctx, -((duk_idx_t) count) - 1);
DUK_ASSERT(h != NULL);
- /* A bit tricky overflow test, see doc/code-issues.txt. */
+ /* A bit tricky overflow test, see doc/code-issues.rst. */
t1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);
t2 = (duk_size_t) (count - 1);
limit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN;
@@ -23338,6 +24233,7 @@ DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context
*ctx) {
* Misc helpers
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Map DUK_HBUFFEROBJECT_ELEM_xxx to duk_hobject class number.
* Sync with duk_hbufferobject.h and duk_hobject.h.
*/
@@ -23352,11 +24248,13 @@ static const duk_uint8_t duk__buffer_class_from_elemtype[9] = {
DUK_HOBJECT_CLASS_FLOAT32ARRAY,
DUK_HOBJECT_CLASS_FLOAT64ARRAY
};
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Map DUK_HBUFFEROBJECT_ELEM_xxx to prototype object built-in index.
* Sync with duk_hbufferobject.h.
*/
-static const duk_uint16_t duk__buffer_proto_from_elemtype[9] = {
+static const duk_uint8_t duk__buffer_proto_from_elemtype[9] = {
DUK_BIDX_UINT8ARRAY_PROTOTYPE,
DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,
DUK_BIDX_INT8ARRAY_PROTOTYPE,
@@ -23367,8 +24265,10 @@ static const duk_uint16_t duk__buffer_proto_from_elemtype[9] = {
DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,
DUK_BIDX_FLOAT64ARRAY_PROTOTYPE
};
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
-/* Map DUK_HBUFFEROBJECT_ELEM_xxx to byte size.
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+/* Map DUK__FLX_xxx to byte size.
*/
static const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {
1, /* DUK__FLD_8BIT */
@@ -23378,7 +24278,9 @@ static const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {
8, /* DUK__FLD_DOUBLE */
0 /* DUK__FLD_VARINT; not relevant here */
};
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Bitfield for each DUK_HBUFFEROBJECT_ELEM_xxx indicating which element types
* are compatible with a blind byte copy for the TypedArray set() method (also
* used for TypedArray constructor). Array index is target buffer elem type,
@@ -23424,7 +24326,9 @@ static duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {
/* xxx -> DUK_HBUFFEROBJECT_ELEM_FLOAT64 */
(1U << DUK_HBUFFEROBJECT_ELEM_FLOAT64)
};
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Shared helper. */
DUK_LOCAL duk_hbufferobject *duk__getrequire_bufobj_this(duk_context *ctx, duk_bool_t
throw_flag) {
duk_hthread *thr;
@@ -23450,19 +24354,25 @@ DUK_LOCAL duk_hbufferobject
*duk__getrequire_bufobj_this(duk_context *ctx, duk_b
}
return NULL;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Check that 'this' is a duk_hbufferobject and return a pointer to it. */
DUK_LOCAL duk_hbufferobject *duk__get_bufobj_this(duk_context *ctx) {
return duk__getrequire_bufobj_this(ctx, 0);
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Check that 'this' is a duk_hbufferobject and return a pointer to it
* (NULL if not).
*/
DUK_LOCAL duk_hbufferobject *duk__require_bufobj_this(duk_context *ctx) {
return duk__getrequire_bufobj_this(ctx, 1);
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Check that value is a duk_hbufferobject and return a pointer to it. */
DUK_LOCAL duk_hbufferobject *duk__require_bufobj_value(duk_context *ctx, duk_idx_t index)
{
duk_hthread *thr;
@@ -23486,7 +24396,9 @@ DUK_LOCAL duk_hbufferobject *duk__require_bufobj_value(duk_context
*ctx, duk_idx
}
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, DUK_STR_NOT_BUFFER);
+ return NULL; /* not reachable */
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
DUK_LOCAL void duk__set_bufobj_buffer(duk_context *ctx, duk_hbufferobject *h_bufobj,
duk_hbuffer *h_val) {
duk_hthread *thr;
@@ -23509,6 +24421,7 @@ DUK_LOCAL void duk__set_bufobj_buffer(duk_context *ctx,
duk_hbufferobject *h_buf
DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
}
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_LOCAL duk_hbufferobject *duk__push_arraybuffer_with_length(duk_context *ctx,
duk_uint_t len) {
duk_hbuffer *h_val;
duk_hbufferobject *h_bufobj;
@@ -23517,11 +24430,11 @@ DUK_LOCAL duk_hbufferobject
*duk__push_arraybuffer_with_length(duk_context *ctx,
h_val = (duk_hbuffer *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_val != NULL);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
-
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
- DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
+ DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
duk__set_bufobj_buffer(ctx, h_bufobj, h_val);
@@ -23529,7 +24442,9 @@ DUK_LOCAL duk_hbufferobject
*duk__push_arraybuffer_with_length(duk_context *ctx,
return h_bufobj;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Shared offset/length coercion helper. */
DUK_LOCAL void duk__resolve_offset_opt_length(duk_context *ctx,
duk_hbufferobject *h_bufarg,
@@ -23589,7 +24504,9 @@ DUK_LOCAL void duk__resolve_offset_opt_length(duk_context *ctx,
fail_range:
duk_error(thr, DUK_ERR_RANGE_ERROR, DUK_STR_INVALID_CALL_ARGS);
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Shared lenient buffer length clamping helper. No negative indices, no
* element/byte shifting.
*/
@@ -23625,7 +24542,9 @@ DUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_context
*ctx,
*out_start_offset = start_offset;
*out_end_offset = end_offset;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Shared lenient buffer length clamping helper. Indices are treated as
* element indices (though output values are byte offsets) which only
* really matters for TypedArray views as other buffer object have a zero
@@ -23691,6 +24610,7 @@ DUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_context
*ctx,
*out_start_offset = start_offset;
*out_end_offset = end_offset;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Indexed read/write helpers (also used from outside this file)
@@ -23703,9 +24623,13 @@ DUK_INTERNAL void
duk_hbufferobject_push_validated_read(duk_context *ctx, duk_hb
switch (h_bufobj->elem_type) {
case DUK_HBUFFEROBJECT_ELEM_UINT8:
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
case DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED:
+#endif
duk_push_uint(ctx, (duk_uint_t) du.uc[0]);
break;
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+ /* These are not needed when only Duktape.Buffer is supported. */
case DUK_HBUFFEROBJECT_ELEM_INT8:
duk_push_int(ctx, (duk_int_t) (duk_int8_t) du.uc[0]);
break;
@@ -23727,6 +24651,7 @@ DUK_INTERNAL void
duk_hbufferobject_push_validated_read(duk_context *ctx, duk_hb
case DUK_HBUFFEROBJECT_ELEM_FLOAT64:
duk_push_number(ctx, (duk_double_t) du.d);
break;
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
default:
DUK_UNREACHABLE();
}
@@ -23747,6 +24672,8 @@ DUK_INTERNAL void duk_hbufferobject_validated_write(duk_context
*ctx, duk_hbuffe
case DUK_HBUFFEROBJECT_ELEM_UINT8:
du.uc[0] = (duk_uint8_t) duk_to_uint32(ctx, -1);
break;
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+ /* These are not needed when only Duktape.Buffer is supported. */
case DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED:
du.uc[0] = (duk_uint8_t) duk_to_uint8clamped(ctx, -1);
break;
@@ -23771,6 +24698,7 @@ DUK_INTERNAL void duk_hbufferobject_validated_write(duk_context
*ctx, duk_hbuffe
case DUK_HBUFFEROBJECT_ELEM_FLOAT64:
du.d = (duk_double_t) duk_to_number(ctx, -1);
break;
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
default:
DUK_UNREACHABLE();
}
@@ -23864,11 +24792,11 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_constructor(duk_context
*ctx) {
h_val = duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_val != NULL);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
- DUK_BIDX_BUFFER_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
+ DUK_BIDX_BUFFER_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
duk__set_bufobj_buffer(ctx, h_bufobj, h_val);
@@ -23884,6 +24812,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_constructor(duk_context *ctx)
{
* Node.js Buffer: constructor
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
/* Internal class is Object: Object.prototype.toString.call(new Buffer(0))
* prints "[object Object]".
@@ -23935,11 +24864,11 @@ DUK_INTERNAL duk_ret_t
duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
h_buf = duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_buf != NULL);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
- DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
+ DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
h_bufobj->buf = h_buf;
@@ -23952,11 +24881,18 @@ DUK_INTERNAL duk_ret_t
duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* ArrayBuffer, DataView, and TypedArray constructors
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx) {
duk_hbufferobject *h_bufobj;
duk_hbuffer *h_val;
@@ -23986,11 +24922,11 @@ DUK_INTERNAL duk_ret_t
duk_bi_arraybuffer_constructor(duk_context *ctx) {
DUK_ASSERT(h_val != NULL);
}
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
-
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
- DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
+ DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
duk__set_bufobj_buffer(ctx, h_bufobj, h_val);
@@ -24001,12 +24937,20 @@ DUK_INTERNAL duk_ret_t
duk_bi_arraybuffer_constructor(duk_context *ctx) {
fail_length:
return DUK_RET_RANGE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+
/* Format of magic, bits:
* 0...1: elem size shift (0-3)
* 2...5: elem type (DUK_HBUFFEROBJECT_ELEM_xxx)
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
duk_hthread *thr;
duk_tval *tv;
@@ -24121,11 +25065,11 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context
*ctx) {
DUK_ASSERT(byte_offset + byte_length <= h_bufarg->length);
DUK_ASSERT((elem_length << shift) == byte_length);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
- proto_bidx);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+ DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
+ proto_bidx);
h_val = h_bufarg->buf;
if (h_val == NULL) {
return DUK_RET_TYPE_ERROR;
@@ -24220,11 +25164,11 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context
*ctx) {
DUK_ASSERT(h_val != NULL);
/* Push the resulting view object and attach the ArrayBuffer. */
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
- proto_bidx);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+ DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
+ proto_bidx);
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
@@ -24344,7 +25288,14 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context
*ctx) {
fail_arguments:
return DUK_RET_RANGE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
duk_hbufferobject *h_bufarg;
duk_hbufferobject *h_bufobj;
@@ -24364,11 +25315,11 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context
*ctx) {
DUK_ASSERT(offset <= h_bufarg->length);
DUK_ASSERT(offset + length <= h_bufarg->length);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
-
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),
- DUK_BIDX_DATAVIEW_PROTOTYPE);
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),
+ DUK_BIDX_DATAVIEW_PROTOTYPE);
h_val = h_bufarg->buf;
if (h_val == NULL) {
@@ -24400,11 +25351,18 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context
*ctx) {
DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* ArrayBuffer.isView()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx) {
duk_hobject *h_obj;
duk_bool_t ret = 0;
@@ -24416,11 +25374,18 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context
*ctx) {
duk_push_boolean(ctx, ret);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer: toString([encoding], [start], [end])
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -24466,11 +25431,18 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context
*ctx) {
type_error:
return DUK_RET_TYPE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Duktape.Buffer: toString(), valueOf()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_buffer_prototype_tostring_shared(duk_context *ctx) {
duk_hthread *thr;
duk_tval *tv;
@@ -24520,11 +25492,18 @@ DUK_INTERNAL duk_ret_t
duk_bi_buffer_prototype_tostring_shared(duk_context *ctx)
type_error:
return DUK_RET_TYPE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_buffer_prototype_tostring_shared(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype: toJSON()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -24562,6 +25541,12 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context
*ctx) {
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype.equals()
@@ -24569,6 +25554,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context
*ctx) {
* Node.js Buffer.compare()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx) {
duk_hthread *thr;
duk_small_uint_t magic;
@@ -24617,11 +25603,18 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context
*ctx) {
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype.fill()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -24687,11 +25680,18 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context
*ctx) {
duk_push_this(ctx);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype.write(string, [offset], [length], [encoding])
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -24731,11 +25731,18 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context
*ctx) {
duk_push_uint(ctx, length);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype.copy()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -24839,6 +25846,12 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context
*ctx) {
fail_bounds:
return DUK_RET_RANGE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* TypedArray.prototype.set()
@@ -24876,6 +25889,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx)
{
* See test-bi-typedarray-proto-set.js.
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
duk_hthread *thr;
duk_hbufferobject *h_this;
@@ -25034,7 +26048,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
(void *) p_dst_base, (long) dst_length));
if (p_src_base >= p_dst_base + dst_length || /* source starts after dest ends */
- p_src_base + src_length < p_dst_base) { /* source ends before dest starts */
+ p_src_base + src_length <= p_dst_base) { /* source ends before dest starts */
no_overlap = 1;
}
@@ -25128,6 +26142,12 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
return 0;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.prototype.slice([start], [end])
@@ -25147,6 +26167,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
* - TypedArray .subarray() arguments are element indices, not byte offsets
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
duk_hthread *thr;
duk_small_int_t magic;
@@ -25191,11 +26212,11 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context
*ctx) {
*/
res_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_this);
- h_bufobj = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),
- DUK_BIDX_OBJECT_PROTOTYPE); /* replaced */
+ h_bufobj = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+ DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),
+ DUK_BIDX_OBJECT_PROTOTYPE); /* replaced */
DUK_ASSERT(h_bufobj != NULL);
res_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_this); /* may be
NULL */
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_bufobj, res_proto);
@@ -25258,11 +26279,18 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context
*ctx) {
DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.isEncoding()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx) {
const char *encoding;
@@ -25273,11 +26301,18 @@ DUK_INTERNAL duk_ret_t
duk_bi_nodejs_buffer_is_encoding(duk_context *ctx) {
duk_push_boolean(ctx, DUK_STRCMP(encoding, "utf8") == 0);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.isBuffer()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
duk_hthread *thr;
duk_tval *tv;
@@ -25307,11 +26342,18 @@ DUK_INTERNAL duk_ret_t
duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
duk_push_boolean(ctx, ret);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.byteLength()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
const char *str;
duk_size_t len;
@@ -25326,11 +26368,18 @@ DUK_INTERNAL duk_ret_t
duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
duk_push_size_t(ctx, len);
return 1;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Node.js Buffer.concat()
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
duk_hthread *thr;
duk_hobject *h_arg;
@@ -25390,11 +26439,11 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context
*ctx) {
return DUK_RET_RANGE_ERROR;
}
- h_bufres = duk_push_bufferobject(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_BUFFEROBJECT |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
- DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
+ h_bufres = duk_push_bufferobject_raw(ctx,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BUFFEROBJECT |
+
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER),
+ DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
DUK_ASSERT(h_bufres != NULL);
p = (duk_uint8_t *) duk_push_fixed_buffer(ctx, total_length);
@@ -25438,6 +26487,12 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context
*ctx) {
return 1; /* return h_bufres */
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
* Shared readfield and writefield methods
@@ -25446,6 +26501,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context
*ctx) {
* types. All offsets are byte based so no offset shifting is needed.
*/
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* Format of magic, bits:
* 0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, 5=unused,
6=unused, 7=unused
* 3: endianness: 0=little, 1=big
@@ -25715,7 +26771,14 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx)
{
return DUK_RET_RANGE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* XXX: split into separate functions for each field type? */
DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
duk_hthread *thr;
@@ -25986,6 +27049,12 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx)
{
}
return DUK_RET_RANGE_ERROR;
}
+#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
+DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ return DUK_RET_UNSUPPORTED_ERROR;
+}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#undef DUK__FLD_8BIT
#undef DUK__FLD_16BIT
@@ -26374,7 +27443,7 @@ DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context
*ctx, const ch
* Note in particular that we must parse whatever toString(), toUTCString(),
* and toISOString() can produce; see E5.1 Section 15.9.4.2.
*
- * Returns 1 to allow tailcalling.
+ * Returns 1 to allow tail calling.
*
* There is much room for improvement here with respect to supporting
* alternative datetime formats. For instance, V8 parses '2012-01-01' as
@@ -26934,7 +28003,7 @@ DUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_context
*ctx, duk_small_ui
}
/* Set timeval to 'this' from dparts, push the new time value onto the
- * value stack and return 1 (caller can then tailcall us). Expects
+ * value stack and return 1 (caller can then tail call us). Expects
* the value stack to contain 'this' on the stack top.
*/
DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_context *ctx, duk_double_t
*dparts, duk_small_uint_t flags) {
@@ -26947,7 +28016,7 @@ DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_context
*ctx, duk_doub
duk_dup_top(ctx); /* -> [ ... this timeval_new timeval_new ] */
duk_put_prop_stridx(ctx, -3, DUK_STRIDX_INT_VALUE);
- /* stack top: new time value, return 1 to allow tailcalls */
+ /* stack top: new time value, return 1 to allow tail calls */
return 1;
}
@@ -27066,7 +28135,7 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx,
duk_small_uint_t fla
/* Helper for component getter calls: check 'this' binding, get the
* internal time value, split it into parts (either as UTC time or
* local time), push a specified component as a return value to the
- * value stack and return 1 (caller can then tailcall us).
+ * value stack and return 1 (caller can then tail call us).
*/
DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx, duk_small_uint_t
flags_and_idx) {
duk_double_t d;
@@ -27098,7 +28167,7 @@ DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx,
duk_small_uint_t flag
* local time), modify one or more components as specified, recompute
* the time value, set it as the internal value. Finally, push the
* new time value as a return value to the value stack and return 1
- * (caller can then tailcall us).
+ * (caller can then tail call us).
*/
DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t
flags_and_maxnargs) {
duk_double_t d;
@@ -28234,12 +29303,15 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context
*ctx) {
case DUK_HTYPE_BUFFER: {
duk_hbuffer *h_buf = (duk_hbuffer *) h;
if (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {
- /* XXX: when alloc_size == 0, dynamic buf ptr may now be NULL, in which case
- * the second allocation does not exist.
- */
- duk_hbuffer_dynamic *h_dyn = (duk_hbuffer_dynamic *) h;
- duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_dynamic)));
- duk_push_uint(ctx, (duk_uint_t) (DUK_HBUFFER_DYNAMIC_GET_SIZE(h_dyn)));
+ if (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {
+ duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_external)));
+ } else {
+ /* When alloc_size == 0 the second allocation may not
+ * actually exist.
+ */
+ duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_dynamic)));
+ }
+ duk_push_uint(ctx, (duk_uint_t) (DUK_HBUFFER_GET_SIZE(h_buf)));
} else {
duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_fixed) +
DUK_HBUFFER_GET_SIZE(h_buf) + 1));
}
@@ -28281,14 +29353,11 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_context
*ctx) {
duk_push_tval(ctx, &act->tv_func);
- pc = (duk_uint_fast32_t) act->pc;
- if (pc > 0) {
- /* Relevant PC is just before current one because PC is
- * post-incremented. This should match what error augment
- * code does.
- */
- pc--;
- }
+ /* Relevant PC is just before current one because PC is
+ * post-incremented. This should match what error augment
+ * code does.
+ */
+ pc = duk_hthread_get_act_prev_pc(thr, act);
duk_push_uint(ctx, (duk_uint_t) pc);
#if defined(DUK_USE_PC2LINE)
@@ -29863,6 +30932,8 @@ DUK_INTERNAL duk_ret_t
duk_bi_global_object_print_helper(duk_context *ctx) {
duk_file *f_out;
#endif
+ DUK_UNREF(thr);
+
magic = duk_get_current_magic(ctx);
DUK_UNREF(magic);
@@ -29917,7 +30988,7 @@ DUK_INTERNAL duk_ret_t
duk_bi_global_object_print_helper(duk_context *ctx) {
p += sz_str;
*p++ = (duk_uint8_t) (i == nargs - 1 ? DUK_ASC_LF : DUK_ASC_SPACE);
}
- DUK_ASSERT((const duk_uint8_t *) p == buf + sz_total);
+ DUK_ASSERT((const duk_uint8_t *) p == buf + sz_buf);
#endif /* DUK_USE_PREFER_SIZE */
} else {
buf = (const duk_uint8_t *) &nl;
@@ -30397,7 +31468,7 @@ DUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx,
duk_uint_fast8_t ch1,
DUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx);
#endif
DUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h);
-#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
+#if defined(DUK_USE_FASTINT)
DUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);
#endif
DUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx);
@@ -31367,7 +32438,7 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
#define DUK__EMIT_1(js_ctx,ch) duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))
#define DUK__EMIT_2(js_ctx,ch1,ch2) duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1),
(duk_uint_fast8_t) (ch2))
#define DUK__EMIT_HSTR(js_ctx,h) duk__emit_hstring((js_ctx), (h))
-#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
+#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)
#define DUK__EMIT_CSTR(js_ctx,p) duk__emit_cstring((js_ctx), (p))
#endif
#define DUK__EMIT_STRIDX(js_ctx,i) duk__emit_stridx((js_ctx), (i))
@@ -31387,7 +32458,7 @@ DUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx,
duk_hstring *h) {
DUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);
}
-#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
+#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)
DUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) {
DUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);
}
@@ -32356,6 +33427,8 @@ DUK_LOCAL void duk__enc_value2(duk_json_enc_ctx *js_ctx) {
#endif
default: {
/* number */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
/* XXX: A fast path for usual integers would be useful when
* fastint support is not enabled.
*/
@@ -32489,9 +33562,13 @@ DUK_LOCAL duk_bool_t
duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* If object has a .toJSON() property, we can't be certain
* that it wouldn't mutate any value arbitrarily, so bail
* out of the fast path.
+ *
+ * If an object is a Proxy we also can't avoid side effects
+ * so abandon.
*/
- if (duk_hobject_hasprop_raw(js_ctx->thr, obj,
DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) {
- DUK_DD(DUK_DDPRINT("object has a .toJSON property, abort fast path"));
+ if (duk_hobject_hasprop_raw(js_ctx->thr, obj,
DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||
+ DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) {
+ DUK_DD(DUK_DDPRINT("object has a .toJSON property or object is a Proxy, abort
fast path"));
goto abort_fastpath;
}
@@ -32598,7 +33675,7 @@ DUK_LOCAL duk_bool_t
duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
tv_val = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i);
- if (DUK_UNLIKELY(DUK_TVAL_IS_UNDEFINED_UNUSED(tv_val))) {
+ if (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_val))) {
/* Gap in array; check for inherited property,
* bail out if one exists. This should be enough
* to support gappy arrays for all practical code.
@@ -32700,6 +33777,9 @@ DUK_LOCAL duk_bool_t
duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* XXX: A fast path for usual integers would be useful when
* fastint support is not enabled.
*/
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
+
/* XXX: Stack discipline is annoying, could be changed in numconv. */
duk_push_tval((duk_context *) js_ctx->thr, tv);
duk__enc_double(js_ctx);
@@ -32780,7 +33860,7 @@ void duk_bi_json_parse_helper(duk_context *ctx,
#ifdef DUK_USE_EXPLICIT_NULL_INIT
/* nothing now */
#endif
- js_ctx->recursion_limit = DUK_JSON_DEC_RECURSION_LIMIT;
+ js_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT;
DUK_ASSERT(js_ctx->recursion_depth == 0);
/* Flag handling currently assumes that flags are consistent. This is OK
@@ -33089,7 +34169,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* slow path has a much larger recursion limit which we'll use if
* necessary.
*/
- DUK_ASSERT(DUK_JSON_ENC_RECURSION_LIMIT >= DUK_JSON_ENC_LOOPARRAY);
+ DUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY);
js_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY;
DUK_ASSERT(js_ctx->recursion_depth == 0);
@@ -33156,7 +34236,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
/* [ ... buf loop (proplist) (gap) holder "" ] */
- js_ctx->recursion_limit = DUK_JSON_ENC_RECURSION_LIMIT;
+ js_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;
DUK_ASSERT(js_ctx->recursion_depth == 0);
undef = duk__enc_value1(js_ctx, idx_holder); /* [ ... holder key ] -> [ ... holder
key val ] */
@@ -34681,7 +35761,7 @@ DUK_INTERNAL duk_ret_t
duk_bi_object_prototype_to_locale_string(duk_context *ctx
return DUK_RET_TYPE_ERROR;
}
duk_dup(ctx, 0); /* -> [ O toString O ] */
- duk_call_method(ctx, 0); /* XXX: call method tailcall? */
+ duk_call_method(ctx, 0); /* XXX: call method tail call? */
return 1;
}
@@ -36440,7 +37520,6 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_context *ctx)
{
DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hthread *thr_resume;
- duk_tval tv_tmp;
duk_tval *tv;
duk_hobject *func;
duk_hobject *caller_func;
@@ -36555,17 +37634,11 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
/* lj value2: thread */
DUK_ASSERT(thr->valstack_bottom < thr->valstack_top);
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value2);
- DUK_TVAL_SET_TVAL(&thr->heap->lj.value2, &thr->valstack_bottom[0]);
- DUK_TVAL_INCREF(thr, &thr->heap->lj.value2);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2,
&thr->valstack_bottom[0]); /* side effects */
/* lj value1: value */
DUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, &thr->valstack_bottom[1]);
- DUK_TVAL_INCREF(thr, &thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1,
&thr->valstack_bottom[1]); /* side effects */
thr->heap->lj.iserror = is_error;
@@ -36599,7 +37672,6 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
- duk_tval tv_tmp;
duk_hobject *caller_func;
duk_small_int_t is_error;
@@ -36682,10 +37754,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
/* lj value1: value */
DUK_ASSERT(thr->valstack_bottom < thr->valstack_top);
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, &thr->valstack_bottom[0]);
- DUK_TVAL_INCREF(thr, &thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1,
&thr->valstack_bottom[0]); /* side effects */
thr->heap->lj.iserror = is_error;
@@ -37422,7 +38491,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st,
duk_hobject *h) {
/* leave out trailing 'unused' elements */
while (a_limit > 0) {
tv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);
- if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (!DUK_TVAL_IS_UNUSED(tv)) {
break;
}
a_limit--;
@@ -37661,10 +38730,17 @@ DUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st,
duk_hbuffer *h) {
}
if (DUK_HBUFFER_HAS_DYNAMIC(h)) {
- duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
- duk_fb_sprintf(fb, "buffer:dynamic:%p:%ld",
- (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),
- (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));
+ if (DUK_HBUFFER_HAS_EXTERNAL(h)) {
+ duk_hbuffer_external *g = (duk_hbuffer_external *) h;
+ duk_fb_sprintf(fb, "buffer:external:%p:%ld",
+ (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),
+ (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));
+ } else {
+ duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
+ duk_fb_sprintf(fb, "buffer:dynamic:%p:%ld",
+ (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),
+ (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));
+ }
} else {
duk_fb_sprintf(fb, "buffer:fixed:%ld", (long) DUK_HBUFFER_GET_SIZE(h));
}
@@ -37744,11 +38820,11 @@ DUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval
*tv) {
}
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED: {
- if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
- duk_fb_put_cstring(fb, "unused");
- } else {
- duk_fb_put_cstring(fb, "undefined");
- }
+ duk_fb_put_cstring(fb, "undefined");
+ break;
+ }
+ case DUK_TAG_UNUSED: {
+ duk_fb_put_cstring(fb, "unused");
break;
}
case DUK_TAG_NULL: {
@@ -37791,6 +38867,7 @@ DUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval
*tv) {
#endif
default: {
/* IEEE double is approximately 16 decimal digits; print a couple extra */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
duk_fb_sprintf(fb, "%.18g", (double) DUK_TVAL_GET_NUMBER(tv));
break;
@@ -38113,6 +39190,7 @@ DUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) {
heap->dbg_processing = 0;
heap->dbg_paused = 0;
heap->dbg_state_dirty = 0;
+ heap->dbg_force_restart = 0;
heap->dbg_step_type = 0;
heap->dbg_step_thread = NULL;
heap->dbg_step_csindex = 0;
@@ -38467,9 +39545,6 @@ DUK_INTERNAL void duk_debug_read_tval(duk_hthread *thr) {
len = duk__debug_read_uint16_raw(thr);
duk__debug_read_hbuffer_raw(thr, len);
break;
- case 0x15:
- duk_push_unused(ctx);
- break;
case 0x16:
duk_push_undefined(ctx);
break;
@@ -38508,6 +39583,7 @@ DUK_INTERNAL void duk_debug_read_tval(duk_hthread *thr) {
duk_push_heapptr(thr, (void *) h);
break;
}
+ case 0x15: /* unused: not accepted in inbound messages */
default:
goto fail;
}
@@ -38682,6 +39758,11 @@ DUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr,
duk_hstring *h) {
(h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0));
}
+DUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) {
+ duk_context *ctx = (duk_context *) thr;
+ duk_debug_write_hstring(thr, duk_safe_to_hstring(ctx, -1));
+}
+
DUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t
length) {
duk_debug_write_strbuf(thr, data, length, 0x13);
}
@@ -38752,8 +39833,10 @@ DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval
*tv) {
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED:
- duk_debug_write_byte(thr,
- DUK_TVAL_IS_UNDEFINED_UNUSED(tv) ? 0x15 : 0x16);
+ duk_debug_write_byte(thr, 0x16);
+ break;
+ case DUK_TAG_UNUSED:
+ duk_debug_write_byte(thr, 0x15);
break;
case DUK_TAG_NULL:
duk_debug_write_byte(thr, 0x17);
@@ -38789,6 +39872,7 @@ DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval
*tv) {
#endif
default:
/* Numbers are normalized to big (network) endian. */
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
du.d = DUK_TVAL_GET_NUMBER(tv);
DUK_DBLUNION_DOUBLE_HTON(&du);
@@ -38861,22 +39945,24 @@ DUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread
*thr) {
duk_uint_fast32_t line;
duk_uint_fast32_t pc;
- if (thr->callstack_top == 0) {
+ act = duk_hthread_get_current_activation(thr); /* may be NULL */
+ if (act == NULL) {
return 0;
}
- act = thr->callstack + thr->callstack_top - 1;
- /* act->pc indicates the next instruction about to be executed. This
- * is usually correct, but for the 'debugger' statement it will be the
- * instruction after that.
+ /* We're conceptually between two opcodes; act->pc indicates the next
+ * instruction to be executed. This is usually the correct pc/line to
+ * indicate in Status. (For the 'debugger' statement this now reports
+ * the pc/line after the debugger statement because the debugger opcode
+ * has already been executed.)
*/
- pc = (duk_uint_fast32_t) act->pc;
+ pc = duk_hthread_get_act_curr_pc(thr, act);
/* XXX: this should be optimized to be a raw query and avoid valstack
* operations if possible.
*/
- duk_push_hobject(ctx, act->func);
+ duk_push_tval(ctx, &act->tv_func);
line = duk_hobject_pc2line_query(ctx, -1, pc);
duk_pop(ctx);
return line;
@@ -38897,20 +39983,62 @@ DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {
duk_debug_write_int(thr, 0);
} else {
act = thr->callstack + thr->callstack_top - 1;
- duk_push_hobject(ctx, act->func);
+ duk_push_tval(ctx, &act->tv_func);
duk_get_prop_string(ctx, -1, "fileName");
- duk_safe_to_string(ctx, -1);
- duk_debug_write_hstring(thr, duk_require_hstring(ctx, -1));
+ duk__debug_write_hstring_safe_top(thr);
duk_get_prop_string(ctx, -2, "name");
- duk_safe_to_string(ctx, -1);
- duk_debug_write_hstring(thr, duk_require_hstring(ctx, -1));
+ duk__debug_write_hstring_safe_top(thr);
duk_pop_3(ctx);
+ /* Report next pc/line to be executed. */
duk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));
- duk_debug_write_uint(thr, (duk_uint32_t) act->pc);
+ duk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));
+ }
+
+ duk_debug_write_eom(thr);
+}
+
+#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)
+DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {
+ /*
+ * NFY <int: 5> <int: fatal> <str: msg> <str: filename>
<int: linenumber> EOM
+ */
+
+ duk_context *ctx = (duk_context *) thr;
+ duk_activation *act;
+ duk_uint32_t pc;
+
+ DUK_ASSERT(thr->valstack_top > thr->valstack); /* At least: ... [err] */
+
+ duk_debug_write_notify(thr, DUK_DBG_CMD_THROW);
+ duk_debug_write_int(thr, fatal);
+
+ /* Report thrown value to client coerced to string */
+ duk_dup(ctx, -1);
+ duk__debug_write_hstring_safe_top(thr);
+ duk_pop(ctx);
+
+ if (duk_is_error(ctx, -1)) {
+ /* Error instance, use augmented error data directly */
+ duk_get_prop_stridx(ctx, -1, DUK_STRIDX_FILE_NAME);
+ duk__debug_write_hstring_safe_top(thr);
+ duk_get_prop_stridx(ctx, -2, DUK_STRIDX_LINE_NUMBER);
+ duk_debug_write_uint(thr, duk_get_uint(ctx, -1));
+ } else {
+ /* For anything other than an Error instance, we calculate the error
+ * location directly from the current activation.
+ */
+ act = thr->callstack + thr->callstack_top - 1;
+ duk_push_tval(ctx, &act->tv_func);
+ duk_get_prop_string(ctx, -1, "fileName");
+ duk__debug_write_hstring_safe_top(thr);
+ pc = duk_hthread_get_act_prev_pc(thr, act);
+ duk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(ctx, -2, pc));
}
+ duk_pop_2(ctx); /* shared pop */
duk_debug_write_eom(thr);
}
+#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY */
/*
* Debug message processing
@@ -39004,7 +40132,7 @@ DUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {
DUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) {
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command version"));
+ DUK_D(DUK_DPRINT("debug command Version"));
duk_debug_write_reply(thr);
duk_debug_write_int(thr, DUK_VERSION);
@@ -39024,7 +40152,7 @@ DUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr,
duk_heap *heap) {
DUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) {
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command triggerstatus"));
+ DUK_D(DUK_DPRINT("debug command TriggerStatus"));
duk_debug_write_reply(thr);
duk_debug_write_eom(thr);
@@ -39032,7 +40160,7 @@ DUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr,
duk_heap *heap
}
DUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) {
- DUK_D(DUK_DPRINT("debug command pause"));
+ DUK_D(DUK_DPRINT("debug command Pause"));
DUK_HEAP_SET_PAUSED(heap);
duk_debug_write_reply(thr);
@@ -39040,7 +40168,7 @@ DUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap
*heap) {
}
DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {
- DUK_D(DUK_DPRINT("debug command resume"));
+ DUK_D(DUK_DPRINT("debug command Resume"));
DUK_HEAP_CLEAR_PAUSED(heap);
duk_debug_write_reply(thr);
@@ -39060,7 +40188,7 @@ DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap
*heap, duk_int3
step_type = DUK_STEP_TYPE_OUT;
}
- DUK_D(DUK_DPRINT("debug command stepinto/stepover/stepout: %d", (int) cmd));
+ DUK_D(DUK_DPRINT("debug command StepInto/StepOver/StepOut: %d", (int) cmd));
line = duk_debug_curr_line(thr);
if (line > 0) {
heap->dbg_paused = 0;
@@ -39079,7 +40207,7 @@ DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap
*heap, duk_int3
DUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) {
duk_small_int_t i;
- DUK_D(DUK_DPRINT("debug command listbreak"));
+ DUK_D(DUK_DPRINT("debug command ListBreak"));
duk_debug_write_reply(thr);
for (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) {
duk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename);
@@ -39098,7 +40226,7 @@ DUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr,
duk_heap *heap) {
filename = duk_debug_read_hstring(thr);
linenumber = (duk_uint32_t) duk_debug_read_int(thr);
- DUK_D(DUK_DPRINT("debug command addbreak: %!O:%ld", (duk_hobject *) filename,
(long) linenumber));
+ DUK_D(DUK_DPRINT("debug command AddBreak: %!O:%ld", (duk_hobject *) filename,
(long) linenumber));
idx = duk_debug_add_breakpoint(thr, filename, linenumber);
if (idx >= 0) {
duk_debug_write_reply(thr);
@@ -39115,7 +40243,7 @@ DUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr,
duk_heap *heap) {
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command delbreak"));
+ DUK_D(DUK_DPRINT("debug command DelBreak"));
idx = (duk_small_uint_t) duk_debug_read_int(thr);
if (duk_debug_remove_breakpoint(thr, idx)) {
duk_debug_write_reply(thr);
@@ -39131,7 +40259,7 @@ DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr,
duk_heap *heap) {
duk_bool_t rc;
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command getvar"));
+ DUK_D(DUK_DPRINT("debug command GetVar"));
str = duk_debug_read_hstring(thr); /* push to stack */
DUK_ASSERT(str != NULL);
@@ -39153,7 +40281,8 @@ DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr,
duk_heap *heap) {
duk_debug_write_reply(thr);
if (rc) {
duk_debug_write_int(thr, 1);
- duk_debug_write_tval(thr, duk_require_tval(ctx, -2));
+ DUK_ASSERT(duk_get_tval(ctx, -2) != NULL);
+ duk_debug_write_tval(thr, duk_get_tval(ctx, -2));
duk_pop_2(ctx);
} else {
duk_debug_write_int(thr, 0);
@@ -39169,12 +40298,13 @@ DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr,
duk_heap *heap) {
duk_tval *tv;
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command putvar"));
+ DUK_D(DUK_DPRINT("debug command PutVar"));
str = duk_debug_read_hstring(thr); /* push to stack */
DUK_ASSERT(str != NULL);
duk_debug_read_tval(thr); /* push to stack */
- tv = duk_require_tval(ctx, -1);
+ tv = duk_get_tval(ctx, -1);
+ DUK_ASSERT(tv != NULL);
if (thr->callstack_top > 0) {
duk_js_putvar_activation(thr,
@@ -39198,6 +40328,7 @@ DUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr,
duk_heap *heap
duk_context *ctx = (duk_context *) thr;
duk_hthread *curr_thr = thr;
duk_activation *curr_act;
+ duk_uint_fast32_t pc;
duk_uint_fast32_t line;
duk_size_t i;
@@ -39210,19 +40341,31 @@ DUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread
*thr, duk_heap *heap
i--;
curr_act = curr_thr->callstack + i;
- /* XXX: optimize to use direct reads,
- * i.e. avoid value stack operations.
+ /* PC/line semantics here are:
+ * - For callstack top we're conceptually between two
+ * opcodes and current PC indicates next line to
+ * execute, so report that (matches Status).
+ * - For other activations we're conceptually still
+ * executing the instruction at PC-1, so report that
+ * (matches error stacktrace behavior).
+ * - See:
https://github.com/svaarala/duktape/issues/281
+ */
+
+ /* XXX: optimize to use direct reads, i.e. avoid
+ * value stack operations.
*/
duk_push_tval(ctx, &curr_act->tv_func);
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_FILE_NAME);
- duk_safe_to_string(ctx, -1);
- duk_debug_write_hstring(thr, duk_get_hstring(ctx, -1));
+ duk__debug_write_hstring_safe_top(thr);
duk_get_prop_stridx(ctx, -2, DUK_STRIDX_NAME);
- duk_safe_to_string(ctx, -1);
- duk_debug_write_hstring(thr, duk_get_hstring(ctx, -1));
- line = duk_hobject_pc2line_query(ctx, -3, curr_act->pc);
+ duk__debug_write_hstring_safe_top(thr);
+ pc = duk_hthread_get_act_curr_pc(thr, curr_act);
+ if (i != curr_thr->callstack_top - 1 && pc > 0) {
+ pc--;
+ }
+ line = duk_hobject_pc2line_query(ctx, -3, pc);
duk_debug_write_uint(thr, (duk_uint32_t) line);
- duk_debug_write_uint(thr, (duk_uint32_t) curr_act->pc);
+ duk_debug_write_uint(thr, (duk_uint32_t) pc);
duk_pop_3(ctx);
}
curr_thr = curr_thr->resumer;
@@ -39285,7 +40428,7 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap
*heap) {
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command eval"));
+ DUK_D(DUK_DPRINT("debug command Eval"));
/* The eval code must be executed within the current (topmost)
* activation. For now, use global object eval() function, with
@@ -39309,7 +40452,7 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap
*heap) {
act = thr->callstack + thr->callstack_top - 1;
fun = DUK_ACT_GET_FUNC(act);
- if (fun && DUK_HOBJECT_IS_COMPILEDFUNCTION(fun)) {
+ if (fun != NULL && DUK_HOBJECT_IS_COMPILEDFUNCTION(fun)) {
/* Direct eval requires that there's a current
* activation and it is an Ecmascript function.
* When Eval is executed from e.g. cooperate API
@@ -39337,7 +40480,8 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap
*heap) {
duk_debug_write_reply(thr);
duk_debug_write_int(thr, (duk_int32_t) eval_err);
- duk_debug_write_tval(thr, duk_require_tval(ctx, -1));
+ DUK_ASSERT(duk_get_tval(ctx, -1) != NULL);
+ duk_debug_write_tval(thr, duk_get_tval(ctx, -1));
duk_debug_write_eom(thr);
duk_pop(ctx);
@@ -39346,7 +40490,7 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap
*heap) {
DUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command detach"));
+ DUK_D(DUK_DPRINT("debug command Detach"));
duk_debug_write_reply(thr);
duk_debug_write_eom(thr);
@@ -39507,7 +40651,7 @@ DUK_LOCAL void duk__debug_dump_strtab_probe(duk_hthread *thr,
duk_heap *heap) {
#endif /* DUK_USE_STRTAB_PROBE */
DUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {
- DUK_D(DUK_DPRINT("debug command dumpheap"));
+ DUK_D(DUK_DPRINT("debug command DumpHeap"));
duk_debug_write_reply(thr);
duk__debug_dump_heap_allocated(thr, heap);
@@ -39530,7 +40674,7 @@ DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr,
duk_heap *heap)
DUK_UNREF(heap);
- DUK_D(DUK_DPRINT("debug command getbytecode"));
+ DUK_D(DUK_DPRINT("debug command GetBytecode"));
duk_debug_write_reply(thr);
if (thr->callstack_top == 0) {
@@ -39544,9 +40688,9 @@ DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr,
duk_heap *heap)
}
DUK_ASSERT(fun == NULL || DUK_HOBJECT_IS_COMPILEDFUNCTION((duk_hobject *) fun));
- if (fun) {
+ if (fun != NULL) {
n = DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(heap, fun);
- duk_debug_write_int(thr, (int) n);
+ duk_debug_write_int(thr, (duk_int32_t) n);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap, fun);
for (i = 0; i < n; i++) {
duk_debug_write_tval(thr, tv);
@@ -39554,7 +40698,7 @@ DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr,
duk_heap *heap)
}
n = DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(heap, fun);
- duk_debug_write_int(thr, (int) n);
+ duk_debug_write_int(thr, (duk_int32_t) n);
fn = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap, fun);
for (i = 0; i < n; i++) {
duk_debug_write_hobject(thr, *fn);
@@ -39689,6 +40833,75 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
return;
}
+/* Halt execution and enter a debugger message loop until execution is resumed
+ * by the client. PC for the current activation may be temporarily decremented
+ * so that the "current" instruction will be shown by the client. This helper
+ * is callable from anywhere, also outside bytecode executor.
+ */
+
+DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) {
+ duk_activation *act;
+ duk_hcompiledfunction *fun;
+ duk_instr_t *old_pc = NULL;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->heap != NULL);
+ DUK_ASSERT(DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap));
+ DUK_ASSERT(thr->heap->dbg_processing == 0);
+
+ DUK_HEAP_SET_PAUSED(thr->heap);
+
+ act = duk_hthread_get_current_activation(thr);
+
+ /* NOTE: act may be NULL if an error is thrown outside of any activation,
+ * which may happen in the case of, e.g. syntax errors.
+ */
+
+ /* Decrement PC if that was requested, this requires a PC sync. */
+ if (act != NULL) {
+ duk_hthread_sync_currpc(thr);
+ old_pc = act->curr_pc;
+ fun = (duk_hcompiledfunction *) DUK_ACT_GET_FUNC(act);
+
+ /* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is
+ * guaranteed to be a non-NULL Ecmascript function.
+ */
+ DUK_ASSERT(act->curr_pc == NULL ||
+ (fun != NULL && DUK_HOBJECT_IS_COMPILEDFUNCTION((duk_hobject *)
fun)));
+ if (use_prev_pc &&
+ act->curr_pc != NULL &&
+ act->curr_pc > DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun)) {
+ act->curr_pc--;
+ }
+ }
+
+ /* Process debug messages until we are no longer paused. */
+
+ /* NOTE: This is a bit fragile. It's important to ensure that neither
+ * duk_debug_send_status() or duk_debug_process_messages() throws an
+ * error or act->curr_pc will never be reset.
+ */
+
+ thr->heap->dbg_processing = 1;
+ duk_debug_send_status(thr);
+ while (thr->heap->dbg_paused) {
+ DUK_ASSERT(thr->heap->dbg_processing);
+ duk_debug_process_messages(thr, 0 /*no_block*/);
+ }
+ thr->heap->dbg_processing = 0;
+
+ /* XXX: Decrementing and restoring act->curr_pc works now, but if the
+ * debugger message loop gains the ability to adjust the current PC
+ * (e.g. a forced jump) restoring the PC here will break. Another
+ * approach would be to use a state flag for the "decrement 1 from
+ * topmost activation's PC" and take it into account whenever dealing
+ * with PC values.
+ */
+ if (act != NULL) {
+ act->curr_pc = old_pc; /* restore PC */
+ }
+}
+
DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block)
{
duk_context *ctx = (duk_context *) thr;
#if defined(DUK_USE_ASSERTIONS)
@@ -39698,6 +40911,8 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread
*thr, duk_bool_t
DUK_ASSERT(thr != NULL);
DUK_UNREF(ctx);
+ DUK_ASSERT(thr->heap != NULL);
+ DUK_ASSERT(DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap));
#if defined(DUK_USE_ASSERTIONS)
entry_top = duk_get_top(ctx);
#endif
@@ -39795,6 +41010,7 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread
*thr, duk_small_
DUK_ASSERT(thr != NULL);
heap = thr->heap;
DUK_ASSERT(heap != NULL);
+ DUK_ASSERT(DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap));
DUK_ASSERT_DISABLE(breakpoint_index >= 0); /* unsigned */
if (breakpoint_index >= heap->dbg_breakpoint_count) {
@@ -39816,6 +41032,7 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread
*thr, duk_small_
heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;
DUK_HSTRING_DECREF(thr, h); /* side effects */
+ DUK_UNREF(h); /* w/o refcounting */
/* Breakpoint entries above the used area are left as garbage. */
@@ -39880,7 +41097,7 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread
*thr, duk_small_
* The user error handler is stored in 'Duktape.errCreate' or
* 'Duktape.errThrow' depending on whether we're augmenting the error at
* creation or throw time. There are several alternatives to this approach,
- * see doc/error-objects.txt for discussion.
+ * see doc/error-objects.rst for discussion.
*
* Note: since further longjmp()s may occur while calling the error handler
* (for many reasons, e.g. a labeled 'break' inside the handler), the
@@ -40006,7 +41223,7 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread
*thr_callstack,
* and cheap to create. It may change arbitrarily from version to version.
* It should be decoded/accessed through version specific accessors only.
*
- * See doc/error-objects.txt.
+ * See doc/error-objects.rst.
*/
DUK_DDD(DUK_DDDPRINT("adding traceback to object: %!T",
@@ -40093,10 +41310,7 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread
*thr_callstack,
* PC points to next instruction, find offending PC. Note that
* PC == 0 for native code.
*/
- pc = thr_callstack->callstack[i].pc;
- if (pc > 0) {
- pc--;
- }
+ pc = duk_hthread_get_act_prev_pc(thr_callstack, thr_callstack->callstack + i);
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits
and non-negative */
d = ((duk_double_t) thr_callstack->callstack[i].flags) * DUK_DOUBLE_2TO32 +
(duk_double_t) pc;
@@ -40178,10 +41392,7 @@ DUK_LOCAL void duk__err_augment_builtin_throw(duk_hthread *thr,
duk_hthread *thr
/* PC points to next instruction, find offending PC. Note that
* PC == 0 for native code.
*/
- pc = act->pc;
- if (pc > 0) {
- pc--;
- }
+ pc = duk_hthread_get_act_prev_pc(thr, act);
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits
and non-negative */
act = NULL; /* invalidated by pushes, so get out of the way */
@@ -40339,6 +41550,37 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
/* include removed: duk_internal.h */
/*
+ * Helper to walk the thread chain and see if there is an active error
+ * catcher. Protected calls or finally blocks aren't considered catching.
+ */
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {
+ /*
+ * XXX: As noted above, a protected API call won't be counted as a
+ * catcher. This is usually convenient, e.g. in the case of a top-
+ * level duk_pcall(), but may not always be desirable. Perhaps add an
+ * argument to treat them as catchers?
+ */
+
+ duk_size_t i;
+
+ DUK_ASSERT(thr != NULL);
+
+ while (thr != NULL) {
+ for (i = 0; i < thr->catchstack_top; i++) {
+ duk_catcher *cat = thr->catchstack + i;
+ if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
+ return 1; /* all we need to know */
+ }
+ }
+ thr = thr->resumer;
+ }
+ return 0;
+}
+#endif /* DUK_USE_DEBUGGER_SUPPORT */
+
+/*
* Get prototype object for an integer error code.
*/
@@ -40374,15 +41616,61 @@ DUK_INTERNAL duk_hobject
*duk_error_prototype_from_code(duk_hthread *thr, duk_er
*/
DUK_INTERNAL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type)
{
- duk_tval tv_tmp;
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ /* If something is thrown with the debugger attached and nobody will
+ * catch it, execution is paused before the longjmp, turning over
+ * control to the debug client. This allows local state to be examined
+ * before the stack is unwound. Errors are not intercepted when debug
+ * message loop is active (e.g. for Eval).
+ */
+
+ /* XXX: Allow customizing the pause and notify behavior at runtime
+ * using debugger runtime flags. For now the behavior is fixed using
+ * config options.
+ */
+#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+ if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap) &&
+ !thr->heap->dbg_processing &&
+ lj_type == DUK_LJ_TYPE_THROW) {
+ duk_context *ctx = (duk_context *) thr;
+ duk_bool_t fatal;
+ duk_hobject *h_obj;
+
+ /* Don't intercept a DoubleError, we may have caused the initial double
+ * fault and attempting to intercept it will cause us to be called
+ * recursively and exhaust the C stack.
+ */
+ h_obj = duk_get_hobject(ctx, -1);
+ if (h_obj == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {
+ DUK_D(DUK_DPRINT("built-in DoubleError instance thrown, not
intercepting"));
+ goto skip_throw_intercept;
+ }
+
+ DUK_D(DUK_DPRINT("throw with debugger attached, report to client"));
+
+ fatal = !duk__have_active_catcher(thr);
+
+#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)
+ /* Report it to the debug client */
+ duk_debug_send_throw(thr, fatal);
+#endif
+
+#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+ if (fatal) {
+ DUK_D(DUK_DPRINT("throw will be fatal, halt before longjmp"));
+ duk_debug_halt_execution(thr, 1 /*use_prev_pc*/);
+ }
+#endif
+ }
+
+ skip_throw_intercept:
+#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT */
+#endif /* DUK_USE_DEBUGGER_SUPPORT */
thr->heap->lj.type = lj_type;
DUK_ASSERT(thr->valstack_top > thr->valstack);
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, thr->valstack_top - 1);
- DUK_TVAL_INCREF(thr, &thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, thr->valstack_top -
1); /* side effects */
duk_pop((duk_context *) thr);
}
@@ -40430,6 +41718,23 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr,
duk_errcode_t code)
thr->heap->handling_error = 1;
+ if (!double_error) {
+ /* Allow headroom for calls during error handling (see GH-191).
+ * We allow space for 10 additional recursions, with one extra
+ * for, e.g. a print() call at the deepest level.
+ */
+ DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX);
+ thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP + 11;
+ }
+
+ DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP
+ 11); /* just making sure */
+
+ /* Sync so that augmentation sees up-to-date activations, NULL
+ * thr->ptr_curr_pc so that it's not used if side effects occur
+ * in augmentation or longjmp handling.
+ */
+ duk_hthread_sync_and_null_currpc(thr);
+
/*
* Create and push an error object onto the top of stack.
* If a "double error" occurs, use a fixed error instance
@@ -40490,10 +41795,11 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr,
duk_errcode_t code)
* Finally, longjmp
*/
- thr->heap->handling_error = 0;
-
duk_err_setup_heap_ljstate(thr, DUK_LJ_TYPE_THROW);
+ thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX; /* reset callstack limit */
+ thr->heap->handling_error = 0;
+
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT, %!iT (after throw
augment)",
(duk_tval *) &thr->heap->lj.value1, (duk_tval *)
&thr->heap->lj.value2));
@@ -40557,10 +41863,18 @@ DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread
*thr, duk_ret_t r
/* include removed: duk_internal.h */
-DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size,
duk_small_uint_t flags) {
+/* Allocate a new duk_hbuffer of a certain type and return a pointer to it
+ * (NULL on error). Write buffer data pointer to 'out_bufdata' (only if
+ * allocation successful).
+ */
+DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size,
duk_small_uint_t flags, void **out_bufdata) {
duk_hbuffer *res = NULL;
+ duk_size_t header_size;
duk_size_t alloc_size;
+ DUK_ASSERT(heap != NULL);
+ DUK_ASSERT(out_bufdata != NULL);
+
DUK_DDD(DUK_DDDPRINT("allocate hbuffer"));
/* Size sanity check. Should not be necessary because caller is
@@ -40570,12 +41884,17 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
*/
if (size > DUK_HBUFFER_MAX_BYTELEN) {
DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size));
- return NULL;
+ return NULL; /* no need to write 'out_bufdata' */
}
- if (flags & DUK_BUF_FLAG_DYNAMIC) {
+ if (flags & DUK_BUF_FLAG_EXTERNAL) {
+ header_size = sizeof(duk_hbuffer_external);
+ alloc_size = sizeof(duk_hbuffer_external);
+ } if (flags & DUK_BUF_FLAG_DYNAMIC) {
+ header_size = sizeof(duk_hbuffer_dynamic);
alloc_size = sizeof(duk_hbuffer_dynamic);
} else {
+ header_size = sizeof(duk_hbuffer_fixed);
alloc_size = sizeof(duk_hbuffer_fixed) + size;
DUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed)); /* no wrapping */
}
@@ -40588,20 +41907,30 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
/* zero everything unless requested not to do so */
#if defined(DUK_USE_ZERO_BUFFER_DATA)
DUK_MEMZERO((void *) res,
- (flags & DUK_BUF_FLAG_NOZERO) ?
- ((flags & DUK_BUF_FLAG_DYNAMIC) ?
- sizeof(duk_hbuffer_dynamic) :
- sizeof(duk_hbuffer_fixed)) :
- alloc_size);
+ (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);
#else
- DUK_MEMZERO((void *) res,
- (flags & DUK_BUF_FLAG_DYNAMIC) ? sizeof(duk_hbuffer_dynamic) :
sizeof(duk_hbuffer_fixed));
+ DUK_MEMZERO((void *) res, header_size);
#endif
- if (flags & DUK_BUF_FLAG_DYNAMIC) {
+ if (flags & DUK_BUF_FLAG_EXTERNAL) {
+ duk_hbuffer_external *h;
+ h = (duk_hbuffer_external *) res;
+ DUK_UNREF(h);
+ *out_bufdata = NULL;
+#if defined(DUK_USE_EXPLICIT_NULL_INIT)
+#if defined(DUK_USE_HEAPPTR16)
+/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
+#else
+ DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);
+#endif
+#endif
+ DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);
+ } else if (flags & DUK_BUF_FLAG_DYNAMIC) {
duk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;
void *ptr;
+
if (size > 0) {
+ DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); /* alloc external with size zero
*/
DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual
buffer"));
#ifdef DUK_USE_ZERO_BUFFER_DATA
ptr = DUK_ALLOC_ZEROED(heap, size);
@@ -40612,9 +41941,11 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
/* Because size > 0, NULL check is correct */
goto error;
}
+ *out_bufdata = ptr;
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);
} else {
+ *out_bufdata = NULL;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_HEAPPTR16)
/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
@@ -40624,6 +41955,8 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
#endif
DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);
}
+ } else {
+ *out_bufdata = (void *) ((duk_hbuffer_fixed *) res + 1);
}
DUK_HBUFFER_SET_SIZE(res, size);
@@ -40631,6 +41964,11 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
DUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);
if (flags & DUK_BUF_FLAG_DYNAMIC) {
DUK_HBUFFER_SET_DYNAMIC(res);
+ if (flags & DUK_BUF_FLAG_EXTERNAL) {
+ DUK_HBUFFER_SET_EXTERNAL(res);
+ }
+ } else {
+ DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));
}
DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);
@@ -40641,7 +41979,7 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap,
duk_size_t size, duk
DUK_DD(DUK_DDPRINT("hbuffer allocation failed"));
DUK_FREE(heap, res);
- return NULL;
+ return NULL; /* no need to write 'out_bufdata' */
}
/* For indirect allocs. */
@@ -40676,6 +42014,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr,
duk_hbuffer_dynamic *buf,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(buf != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));
/*
* Maximum size check
@@ -40731,12 +42070,14 @@ DUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr,
duk_hbuffer_dynamic *buf)
DUK_ASSERT(thr != NULL);
DUK_ASSERT(buf != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));
duk_hbuffer_resize(thr, buf, 0);
}
/* include removed: duk_internal.h */
#line 2 "duk_hbufferobject_misc.c"
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_bufobj,
duk_uint_t len) {
duk_uint_t buf_size;
duk_uint_t buf_avail;
@@ -40753,6 +42094,7 @@ DUK_INTERNAL duk_uint_t
duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_
return buf_avail >= len ? len : buf_avail;
}
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#line 1 "duk_heap_alloc.c"
/*
* duk_heap allocation and freeing.
@@ -40812,7 +42154,7 @@ DUK_INTERNAL void duk_free_hbuffer_inner(duk_heap *heap,
duk_hbuffer *h) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
- if (DUK_HBUFFER_HAS_DYNAMIC(h)) {
+ if (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) {
duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
DUK_DDD(DUK_DDDPRINT("free dynamic buffer %p", (void *)
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));
DUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));
@@ -41273,6 +42615,7 @@ DUK_LOCAL void duk__dump_type_sizes(void) {
DUK__DUMPSZ(duk_hbuffer);
DUK__DUMPSZ(duk_hbuffer_fixed);
DUK__DUMPSZ(duk_hbuffer_dynamic);
+ DUK__DUMPSZ(duk_hbuffer_external);
DUK__DUMPSZ(duk_propaccessor);
DUK__DUMPSZ(duk_propvalue);
DUK__DUMPSZ(duk_propdesc);
@@ -41409,6 +42752,10 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
DUK_D(DUK_DPRINT("self tests passed"));
#endif
+ /*
+ * Computed values (e.g. INFINITY)
+ */
+
#ifdef DUK_USE_COMPUTED_NAN
do {
/* Workaround for some exotic platforms where NAN is missing
@@ -41425,10 +42772,6 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
} while (0);
#endif
- /*
- * Computed values (e.g. INFINITY)
- */
-
#ifdef DUK_USE_COMPUTED_INFINITY
do {
/* Similar workaround for INFINITY. */
@@ -41514,7 +42857,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
/* res->mark_and_sweep_trigger_counter == 0 -> now causes immediate GC; which is
OK */
res->call_recursion_depth = 0;
- res->call_recursion_limit = DUK_HEAP_DEFAULT_CALL_RECURSION_LIMIT;
+ res->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT;
/* XXX: use the pointer as a seed for now: mix in time at least */
@@ -41532,8 +42875,8 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
#endif
DUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN); /* zero */
- DUK_TVAL_SET_UNDEFINED_UNUSED(&res->lj.value1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&res->lj.value2);
+ DUK_TVAL_SET_UNDEFINED(&res->lj.value1);
+ DUK_TVAL_SET_UNDEFINED(&res->lj.value2);
#if (DUK_STRTAB_INITIAL_SIZE < DUK_UTIL_MIN_HASH_PRIME)
#error initial heap stringtable size is defined incorrectly
@@ -41847,7 +43190,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h)
{
duk_tval *tv;
tv = t->valstack;
- while (tv < t->valstack_end) {
+ while (tv < t->valstack_top) {
duk__mark_tval(heap, tv);
tv++;
}
@@ -41892,7 +43235,7 @@ DUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h)
{
}
DUK_HEAPHDR_SET_REACHABLE(h);
- if (heap->mark_and_sweep_recursion_depth >=
DUK_HEAP_MARK_AND_SWEEP_RECURSION_LIMIT) {
+ if (heap->mark_and_sweep_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {
/* log this with a normal debug level because this should be relatively rare */
DUK_D(DUK_DPRINT("mark-and-sweep recursion limit reached, marking as temproot:
%p", (void *) h));
DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);
@@ -42809,6 +44152,52 @@ DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {
#endif /* DUK_USE_ASSERTIONS */
/*
+ * Finalizer torture. Do one fake finalizer call which causes side effects
+ * similar to one or more finalizers on actual objects.
+ */
+
+#if defined(DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE)
+DUK_LOCAL duk_ret_t duk__markandsweep_fake_finalizer(duk_context *ctx) {
+ DUK_D(DUK_DPRINT("fake mark-and-sweep torture finalizer executed"));
+
+ /* Require a lot of stack to force a value stack grow/shrink.
+ * Recursive mark-and-sweep is prevented by allocation macros
+ * so this won't trigger another mark-and-sweep.
+ */
+ duk_require_stack(ctx, 100000);
+
+ /* XXX: do something to force a callstack grow/shrink, perhaps
+ * just a manual forced resize or a forced relocating realloc?
+ */
+
+ return 0;
+}
+
+DUK_LOCAL void duk__markandsweep_torture_finalizer(duk_hthread *thr) {
+ duk_context *ctx;
+ duk_int_t rc;
+
+ DUK_ASSERT(thr != NULL);
+ ctx = (duk_context *) thr;
+
+ /* Avoid fake finalization when callstack limit has been reached.
+ * Otherwise a callstack limit error will be created, then refzero'ed.
+ */
+ if (thr->heap->call_recursion_depth >= thr->heap->call_recursion_limit
||
+ thr->callstack_size + 2 * DUK_CALLSTACK_GROW_STEP >= thr->callstack_max
/*approximate*/) {
+ DUK_D(DUK_DPRINT("call recursion depth reached, avoid fake mark-and-sweep torture
finalizer"));
+ return;
+ }
+
+ /* Run fake finalizer. Avoid creating unnecessary garbage. */
+ duk_push_c_function(ctx, duk__markandsweep_fake_finalizer, 0 /*nargs*/);
+ rc = duk_pcall(ctx, 0 /*nargs*/);
+ DUK_UNREF(rc); /* ignored */
+ duk_pop(ctx);
+}
+#endif /* DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE */
+
+/*
* Main mark-and-sweep function.
*
* 'flags' represents the features requested by the caller. The current
@@ -42829,6 +44218,9 @@ DUK_INTERNAL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap,
duk_small_uint_t
* If we don't have a thread, the entire mark-and-sweep is now
* skipped (although we could just skip finalizations).
*/
+ /* XXX: if thr != NULL, the thr may still be in the middle of
+ * initialization; improve the thread viability test.
+ */
thr = duk__get_temp_hthread(heap);
if (thr == NULL) {
DUK_D(DUK_DPRINT("temporary hack: gc skipped because we don't have a temp
thread"));
@@ -42995,10 +44387,26 @@ DUK_INTERNAL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap,
duk_small_uint_t
* already happened, this is probably good enough for now.
*/
- if (!(flags & DUK_MS_FLAG_NO_FINALIZERS)) {
- duk__run_object_finalizers(heap);
+#if defined(DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE)
+ /* Cannot simulate individual finalizers because finalize_list only
+ * contains objects with actual finalizers. But simulate side effects
+ * from finalization by doing a bogus function call and resizing the
+ * stacks.
+ */
+ if (flags & DUK_MS_FLAG_NO_FINALIZERS) {
+ DUK_D(DUK_DPRINT("skip mark-and-sweep torture finalizer, DUK_MS_FLAG_NO_FINALIZERS
is set"));
+ } else if (!(thr->valstack != NULL && thr->callstack != NULL &&
thr->catchstack != NULL)) {
+ DUK_D(DUK_DPRINT("skip mark-and-sweep torture finalizer, thread not yet
viable"));
} else {
+ DUK_D(DUK_DPRINT("run mark-and-sweep torture finalizer"));
+ duk__markandsweep_torture_finalizer(thr);
+ }
+#endif /* DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE */
+
+ if (flags & DUK_MS_FLAG_NO_FINALIZERS) {
DUK_D(DUK_DPRINT("finalizer run skipped because DUK_MS_FLAG_NO_FINALIZERS is
set"));
+ } else {
+ duk__run_object_finalizers(heap);
}
/*
@@ -43628,7 +45036,7 @@ DUK_LOCAL void duk__refcount_finalize_hobject(duk_hthread *thr,
duk_hobject *h)
duk_tval *tv;
tv = t->valstack;
- while (tv < t->valstack_end) {
+ while (tv < t->valstack_top) {
duk_tval_decref(thr, tv);
tv++;
}
@@ -43674,6 +45082,60 @@ DUK_INTERNAL void duk_heaphdr_refcount_finalize(duk_hthread *thr,
duk_heaphdr *h
}
}
+#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)
+DUK_LOCAL duk_ret_t duk__refcount_fake_finalizer(duk_context *ctx) {
+ DUK_UNREF(ctx);
+ DUK_D(DUK_DPRINT("fake refcount torture finalizer executed"));
+#if 0
+ DUK_DD(DUK_DDPRINT("fake torture finalizer for: %!T", duk_get_tval(ctx, 0)));
+#endif
+ /* Require a lot of stack to force a value stack grow/shrink. */
+ duk_require_stack(ctx, 100000);
+
+ /* XXX: do something to force a callstack grow/shrink, perhaps
+ * just a manual forced resize?
+ */
+ return 0;
+}
+
+DUK_LOCAL void duk__refcount_run_torture_finalizer(duk_hthread *thr, duk_hobject *obj) {
+ duk_context *ctx;
+ duk_int_t rc;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(obj != NULL);
+ ctx = (duk_context *) thr;
+
+ /* Avoid fake finalization for the duk__refcount_fake_finalizer function
+ * itself, otherwise we're in infinite recursion.
+ */
+ if (DUK_HOBJECT_HAS_NATIVEFUNCTION(obj)) {
+ if (((duk_hnativefunction *) obj)->func == duk__refcount_fake_finalizer) {
+ DUK_DD(DUK_DDPRINT("avoid fake torture finalizer for duk__refcount_fake_finalizer
itself"));
+ return;
+ }
+ }
+ /* Avoid fake finalization when callstack limit has been reached.
+ * Otherwise a callstack limit error will be created, then refzero'ed,
+ * and we're in an infinite loop.
+ */
+ if (thr->heap->call_recursion_depth >= thr->heap->call_recursion_limit
||
+ thr->callstack_size + 2 * DUK_CALLSTACK_GROW_STEP >= thr->callstack_max
/*approximate*/) {
+ DUK_D(DUK_DPRINT("call recursion depth reached, avoid fake torture
finalizer"));
+ return;
+ }
+
+ /* Run fake finalizer. Avoid creating new refzero queue entries
+ * so that we are not forced into a forever loop.
+ */
+ duk_push_c_function(ctx, duk__refcount_fake_finalizer, 1 /*nargs*/);
+ duk_push_hobject(ctx, obj);
+ rc = duk_pcall(ctx, 1);
+ DUK_UNREF(rc); /* ignored */
+ duk_pop(ctx);
+}
+#endif /* DUK_USE_REFZERO_FINALIZER_TORTURE */
+
/*
* Refcount memory freeing loop.
*
@@ -43723,6 +45185,20 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, h1) == NULL);
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h1) == DUK_HTYPE_OBJECT); /* currently, always the
case */
+#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)
+ /* Torture option to shake out finalizer side effect issues:
+ * make a bogus function call for every finalizable object,
+ * essentially simulating the case where everything has a
+ * finalizer.
+ */
+ DUK_DD(DUK_DDPRINT("refzero torture enabled, fake finalizer"));
+ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h1) == 0);
+ DUK_HEAPHDR_PREINC_REFCOUNT(h1); /* bump refcount to prevent refzero during finalizer
processing */
+ duk__refcount_run_torture_finalizer(thr, obj); /* must never longjmp */
+ DUK_HEAPHDR_PREDEC_REFCOUNT(h1); /* remove artificial bump */
+ DUK_ASSERT_DISABLE(h1->h_refcount >= 0); /* refcount is unsigned, so always true
*/
+#endif
+
/*
* Finalizer check.
*
@@ -45288,6 +46764,7 @@ DUK_INTERNAL duk_hstring
*duk_heap_string_intern_u32_checked(duk_hthread *thr, d
}
/* find and remove string from stringtable; caller must free the string itself */
+#if defined(DUK_USE_REFERENCE_COUNTING)
DUK_INTERNAL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h) {
DUK_DDD(DUK_DDDPRINT("remove string from stringtable: %!O", (duk_heaphdr *)
h));
@@ -45306,6 +46783,7 @@ DUK_INTERNAL void duk_heap_string_remove(duk_heap *heap,
duk_hstring *h) {
#error internal error, invalid strtab options
#endif
}
+#endif
#if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_MS_STRINGTABLE_RESIZE)
DUK_INTERNAL void duk_heap_force_strtab_resize(duk_heap *heap) {
@@ -45579,6 +47057,7 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_heap *heap,
duk_uint_t hobject_f
duk__init_object_parts(heap, &res->obj, hobject_flags);
#ifdef DUK_USE_EXPLICIT_NULL_INIT
+ res->ptr_curr_pc = NULL;
res->heap = NULL;
res->valstack = NULL;
res->valstack_end = NULL;
@@ -46002,7 +47481,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx,
duk_small_uint
duk_tval *tv;
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
- if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (DUK_TVAL_IS_UNUSED(tv)) {
continue;
}
k = duk_heap_string_intern_u32_checked(thr, i);
@@ -46042,7 +47521,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx,
duk_small_uint
}
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||
-
!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr,
i)->v));
+ !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr,
i)->v));
duk_push_hstring(ctx, k);
duk_push_true(ctx);
@@ -46159,7 +47638,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context
*ctx, duk_bool_t
k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);
DUK_ASSERT(k != NULL);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));
- DUK_ASSERT(!DUK_TVAL_IS_UNDEFINED_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e,
idx).v));
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));
idx++;
@@ -46372,7 +47851,7 @@ DUK_INTERNAL duk_bool_t
duk_hobject_prototype_chain_contains(duk_hthread *thr, d
return 0;
}
-DUK_INTERNAL void duk_hobject_set_prototype(duk_hthread *thr, duk_hobject *h, duk_hobject
*p) {
+DUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h,
duk_hobject *p) {
#ifdef DUK_USE_REFERENCE_COUNTING
duk_hobject *tmp;
@@ -46394,7 +47873,7 @@ DUK_INTERNAL void duk_hobject_set_prototype(duk_hthread *thr,
duk_hobject *h, du
*
* The run-time pc2line data is bit-packed, and documented in:
*
- * doc/function-objects.txt
+ * doc/function-objects.rst
*/
/* include removed: duk_internal.h */
@@ -46427,7 +47906,7 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr,
duk_compiler_instr
duk_push_dynamic_buffer(ctx, (duk_size_t) curr_offset);
h_buf = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_buf != NULL);
- DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf));
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf));
hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);
DUK_ASSERT(hdr != NULL);
@@ -46528,7 +48007,7 @@ DUK_LOCAL duk_uint_fast32_t
duk__hobject_pc2line_query_raw(duk_hthread *thr, duk
duk_uint_fast32_t curr_line;
DUK_ASSERT(buf != NULL);
- DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) &&
!DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf));
DUK_UNREF(thr);
/*
@@ -46627,7 +48106,7 @@ DUK_INTERNAL duk_uint_fast32_t
duk_hobject_pc2line_query(duk_context *ctx, duk_i
duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_PC2LINE);
pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
if (pc2line != NULL) {
- DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) &&
!DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));
line = duk__hobject_pc2line_query_raw((duk_hthread *) ctx, pc2line, (duk_uint_fast32_t)
pc);
} else {
line = 0;
@@ -46643,8 +48122,8 @@ DUK_INTERNAL duk_uint_fast32_t
duk_hobject_pc2line_query(duk_context *ctx, duk_i
* Hobject property set/get functionality.
*
* This is very central functionality for size, performance, and compliance.
- * It is also rather intricate; see hobject-algorithms.txt for discussion on
- * the algorithms and memory-management.txt for discussion on refcounts and
+ * It is also rather intricate; see hobject-algorithms.rst for discussion on
+ * the algorithms and memory-management.rst for discussion on refcounts and
* side effect issues.
*
* Notes:
@@ -46889,7 +48368,7 @@ DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject
*obj, duk_uint
a = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);
for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv = a++;
- if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (!DUK_TVAL_IS_UNUSED(tv)) {
used++;
highest_idx = i;
}
@@ -47320,7 +48799,7 @@ void duk__realloc_props(duk_hthread *thr,
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
- if (DUK_TVAL_IS_UNDEFINED_UNUSED(tv1)) {
+ if (DUK_TVAL_IS_UNUSED(tv1)) {
continue;
}
@@ -47412,7 +48891,7 @@ void duk__realloc_props(duk_hthread *thr,
/* fill new entries with -unused- (required, gc reachable) */
for (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {
duk_tval *tv = &new_a[i];
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
+ DUK_TVAL_SET_UNUSED(tv);
}
} else {
#ifdef DUK_USE_ASSERTIONS
@@ -47423,7 +48902,7 @@ void duk__realloc_props(duk_hthread *thr,
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
/* current assertion is quite strong: decref's and set to unused */
- DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));
}
}
#endif
@@ -47566,7 +49045,7 @@ void duk__realloc_props(duk_hthread *thr,
i--;
DUK_ASSERT(new_e_k != NULL);
DUK_ASSERT(new_e_k[i] != NULL);
- DUK_HSTRING_DECREF(thr, new_e_k[i]);
+ DUK_HSTRING_DECREF(thr, new_e_k[i]); /* side effects */
}
#ifdef DUK_USE_MARK_AND_SWEEP
@@ -47973,8 +49452,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap
*heap, duk_hobje
DUK_ASSERT(obj != NULL);
DUK_ASSERT(tv_out != NULL);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv_out);
-
/* always in entry part, no need to look up parents etc */
duk_hobject_find_existing_entry(heap, obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx,
&h_idx);
if (e_idx >= 0) {
@@ -47982,6 +49459,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap
*heap, duk_hobje
DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
return 1;
}
+ DUK_TVAL_SET_UNDEFINED(tv_out);
return 0;
}
@@ -48251,7 +49729,7 @@ DUK_LOCAL duk_bool_t duk__get_own_property_desc_raw(duk_hthread
*thr, duk_hobjec
if (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {
if (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
- if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (!DUK_TVAL_IS_UNUSED(tv)) {
DUK_DDD(DUK_DDDPRINT("-> found in array part"));
if (flags & DUK__DESC_FLAG_PUSH_VALUE) {
duk_push_tval(ctx, tv);
@@ -48653,7 +50131,7 @@ DUK_LOCAL duk_tval
*duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, d
DUK_DDD(DUK_DDDPRINT("key is a valid array index and inside array part"));
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);
- if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (!DUK_TVAL_IS_UNUSED(tv)) {
DUK_DDD(DUK_DDDPRINT("-> fast path successful"));
return tv;
}
@@ -48665,7 +50143,6 @@ DUK_LOCAL duk_tval
*duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, d
DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr,
duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val, duk_propdesc *temp_desc) {
duk_tval *tv;
duk_uint32_t idx;
- duk_tval tv_tmp;
duk_uint32_t old_len, new_len;
if (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&
@@ -48722,10 +50199,7 @@ DUK_LOCAL duk_bool_t
duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr,
}
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_TVAL(tv, tv_val);
- DUK_TVAL_INCREF(thr, tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* note: may trigger gc and props compaction, must
be last */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */
DUK_DDD(DUK_DDDPRINT("array fast path success for index %ld", (long) idx));
return 1;
@@ -49185,6 +50659,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr,
duk_tval *tv_obj,
default: {
/* number */
DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number
prototype"));
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));
curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];
break;
@@ -49580,7 +51055,6 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
duk_uint32_t arr_idx;
duk_hstring *key;
duk_tval *tv;
- duk_tval tv_tmp;
duk_bool_t rc;
DUK_DDD(DUK_DDDPRINT("new array length smaller than old (%ld -> %ld), "
@@ -49628,9 +51102,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
while (i > new_len) {
i--;
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */
}
*out_result_len = new_len;
@@ -49976,10 +51448,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr,
duk_tval *tv_obj,
* the fast path will incorrectly ignore them.
*
* This fast path could be made compliant by falling through
- * to the slow path if the previous value was UNDEFINED_UNUSED.
- * This would also remove the need to check for extensibility.
- * Right now a non-extensible array is slower than an extensible
- * one as far as writes are concerned.
+ * to the slow path if the previous value was UNUSED. This would
+ * also remove the need to check for extensibility. Right now a
+ * non-extensible array is slower than an extensible one as far
+ * as writes are concerned.
*
* The fast path behavior is documented in more detail here:
* tests/ecmascript/test-misc-array-fast-write.js
@@ -50387,14 +51859,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr,
duk_tval *tv_obj,
}
if (desc.e_idx >= 0) {
- duk_tval tv_tmp;
-
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv));
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_TVAL(tv, tv_val);
- DUK_TVAL_INCREF(thr, tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* note: may trigger gc and props compaction, must
be last */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */
/* don't touch property attributes or hash part */
DUK_DD(DUK_DDPRINT("put to an existing entry at index %ld -> new value
%!iT",
(long) desc.e_idx, (duk_tval *) tv));
@@ -50403,15 +51870,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr,
duk_tval *tv_obj,
* above is pointless for them. The check could be avoided with some
* refactoring but is probably not worth it.
*/
- duk_tval tv_tmp;
DUK_ASSERT(desc.a_idx >= 0);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);
DUK_DDD(DUK_DDDPRINT("previous array value: %!iT", (duk_tval *) tv));
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_TVAL(tv, tv_val);
- DUK_TVAL_INCREF(thr, tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* note: may trigger gc and props compaction, must
be last */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */
DUK_DD(DUK_DDPRINT("put to an existing array entry at index %ld -> new value
%!iT",
(long) desc.a_idx, (duk_tval *) tv));
}
@@ -50568,7 +52031,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr,
duk_tval *tv_obj,
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, arr_idx);
/* prev value must be unused, no decref */
- DUK_ASSERT(DUK_TVAL_IS_UNDEFINED_UNUSED(tv));
+ DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));
DUK_TVAL_SET_TVAL(tv, tv_val);
DUK_TVAL_INCREF(thr, tv);
DUK_DD(DUK_DDPRINT("put to new array entry: %ld -> %!T",
@@ -50749,7 +52212,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr,
duk_tval *tv_obj,
DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj,
duk_hstring *key, duk_small_uint_t flags) {
duk_propdesc desc;
duk_tval *tv;
- duk_tval tv_tmp;
duk_uint32_t arr_idx;
duk_bool_t throw_flag;
duk_bool_t force_flag;
@@ -50790,9 +52252,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr,
duk_hobject *o
DUK_ASSERT(desc.e_idx < 0);
tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */
goto success;
} else {
DUK_ASSERT(desc.a_idx < 0);
@@ -50823,21 +52283,20 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread
*thr, duk_hobject *o
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);
DUK_UNREF(tmp);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);
DUK_UNREF(tmp);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
} else {
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
- /* this is not strictly necessary because if key == NULL, value MUST be ignored */
+#if 0
+ /* Not strictly necessary because if key == NULL, flag MUST be ignored. */
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);
- DUK_TVAL_SET_UNDEFINED_UNUSED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj,
desc.e_idx));
+#endif
/* remove key */
DUK_DDD(DUK_DDDPRINT("before removing key, e_idx %ld, key %p, key at slot
%p",
@@ -50845,7 +52304,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr,
duk_hobject *o
DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx));
DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));
DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);
- DUK_HSTRING_DECREF(thr, key);
+ DUK_HSTRING_DECREF(thr, key); /* side effects */
goto success;
}
@@ -51104,7 +52563,6 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread
*thr, duk_hob
duk_propdesc desc;
duk_uint32_t arr_idx;
duk_int_t e_idx;
- duk_tval tv_tmp;
duk_tval *tv1 = NULL;
duk_tval *tv2 = NULL;
duk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK; /* mask out flags not
actually stored */
@@ -51184,7 +52642,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread
*thr, duk_hob
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
/* new entry: previous value is garbage; set to undefined to share write_value */
- DUK_TVAL_SET_UNDEFINED_ACTUAL(tv1);
+ DUK_TVAL_SET_UNDEFINED(tv1);
goto write_value;
write_value:
@@ -51194,10 +52652,7 @@ DUK_INTERNAL void
duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
DUK_DDD(DUK_DDDPRINT("writing/updating value: %!T -> %!T",
(duk_tval *) tv1, (duk_tval *) tv2));
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, tv2);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
goto pop_exit;
pop_exit:
@@ -51223,7 +52678,6 @@ DUK_INTERNAL void
duk_hobject_define_property_internal_arridx(duk_hthread *thr,
duk_context *ctx = (duk_context *) thr;
duk_hstring *key;
duk_tval *tv1, *tv2;
- duk_tval tv_tmp;
DUK_DDD(DUK_DDDPRINT("define new property (internal) arr_idx fast path: thr=%p,
obj=%!O, "
"arr_idx=%ld, flags=0x%02lx, val=%!T",
@@ -51250,10 +52704,7 @@ DUK_INTERNAL void
duk_hobject_define_property_internal_arridx(duk_hthread *thr,
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
tv2 = duk_require_tval(ctx, -1);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, tv2);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
duk_pop(ctx); /* [ ...val ] -> [ ... ] */
return;
@@ -51834,7 +53285,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
duk_tval *tv_tmp = duk_require_tval(ctx, idx_value);
DUK_TVAL_SET_TVAL(&tv, tv_tmp);
} else {
- DUK_TVAL_SET_UNDEFINED_ACTUAL(&tv); /* default value */
+ DUK_TVAL_SET_UNDEFINED(&tv); /* default value */
}
if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
@@ -52004,7 +53455,6 @@ void duk_hobject_define_property_helper(duk_context *ctx,
}
} else {
duk_bool_t rc;
- duk_tval tv_tmp;
duk_tval *tv1;
/* curr is data, desc is accessor */
@@ -52026,9 +53476,8 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ /* XXX: just decref */
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
@@ -52069,13 +53518,13 @@ void duk_hobject_define_property_helper(duk_context *ctx,
tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
- DUK_TVAL_SET_UNDEFINED_ACTUAL(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj,
curr.e_idx));
+ DUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj,
curr.e_idx));
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);
@@ -52161,7 +53610,6 @@ void duk_hobject_define_property_helper(duk_context *ctx,
if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
duk_tval *tv1, *tv2;
- duk_tval tv_tmp;
DUK_DDD(DUK_DDDPRINT("array index, new property attributes match array defaults,
update in-place"));
@@ -52171,10 +53619,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
tv2 = duk_require_tval(ctx, idx_value);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, tv2);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
goto success_exotics;
}
@@ -52205,7 +53650,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);
DUK_HOBJECT_INCREF_ALLOWNULL(thr, set);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
}
if (has_get) {
duk_hobject *tmp;
@@ -52217,21 +53662,17 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_UNREF(tmp);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);
DUK_HOBJECT_INCREF_ALLOWNULL(thr, get);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
}
if (has_value) {
duk_tval *tv1, *tv2;
- duk_tval tv_tmp;
DUK_DDD(DUK_DDDPRINT("update existing property value"));
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
tv2 = duk_require_tval(ctx, idx_value);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, tv2);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
}
/*
@@ -52549,7 +53990,7 @@ DUK_INTERNAL duk_bool_t
duk_hobject_object_is_sealed_frozen_helper(duk_hthread *
*/
for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
- if (!DUK_TVAL_IS_UNDEFINED_UNUSED(tv)) {
+ if (!DUK_TVAL_IS_UNUSED(tv)) {
return 0;
}
}
@@ -52640,11 +54081,14 @@ DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap,
duk_hthread *thr
}
DUK_MEMZERO(thr->valstack, alloc_size);
thr->valstack_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;
+#if !defined(DUK_USE_PREFER_SIZE)
+ thr->valstack_size = DUK_VALSTACK_INITIAL_SIZE;
+#endif
thr->valstack_bottom = thr->valstack;
thr->valstack_top = thr->valstack;
for (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->valstack[i]);
+ DUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);
}
/* callstack */
@@ -53421,6 +54865,70 @@ DUK_INTERNAL duk_activation
*duk_hthread_get_current_activation(duk_hthread *thr
return NULL;
}
}
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr,
duk_activation *act) {
+ duk_instr_t *bcode;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(act != NULL);
+ DUK_UNREF(thr);
+
+ /* XXX: store 'bcode' pointer to activation for faster lookup? */
+ if (act->func && DUK_HOBJECT_IS_COMPILEDFUNCTION(act->func)) {
+ bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *)
(act->func));
+ return (duk_uint_fast32_t) (act->curr_pc - bcode);
+ }
+ return 0;
+}
+#endif /* DUK_USE_DEBUGGER_SUPPORT */
+
+DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr,
duk_activation *act) {
+ duk_instr_t *bcode;
+ duk_uint_fast32_t ret;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(act != NULL);
+ DUK_UNREF(thr);
+
+ if (act->func && DUK_HOBJECT_IS_COMPILEDFUNCTION(act->func)) {
+ bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *)
(act->func));
+ ret = (duk_uint_fast32_t) (act->curr_pc - bcode);
+ if (ret > 0) {
+ ret--;
+ }
+ return ret;
+ }
+ return 0;
+}
+
+/* Write bytecode executor's curr_pc back to topmost activation (if any). */
+DUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {
+ duk_activation *act;
+
+ DUK_ASSERT(thr != NULL);
+
+ if (thr->ptr_curr_pc != NULL) {
+ /* ptr_curr_pc != NULL only when bytecode executor is active. */
+ DUK_ASSERT(thr->callstack_top > 0);
+ act = thr->callstack + thr->callstack_top - 1;
+ act->curr_pc = *thr->ptr_curr_pc;
+ }
+}
+
+DUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {
+ duk_activation *act;
+
+ DUK_ASSERT(thr != NULL);
+
+ if (thr->ptr_curr_pc != NULL) {
+ /* ptr_curr_pc != NULL only when bytecode executor is active. */
+ DUK_ASSERT(thr->callstack_top > 0);
+ act = thr->callstack + thr->callstack_top - 1;
+ act->curr_pc = *thr->ptr_curr_pc;
+ thr->ptr_curr_pc = NULL;
+ }
+}
#line 1 "duk_hthread_stacks.c"
/*
* Manipulation of thread stacks (valstack, callstack, catchstack).
@@ -53930,7 +55438,7 @@ DUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread
*entry_curr_th
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
-#if 0
+#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP)
if (entry_curr_thread == NULL) {
thr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;
thr->heap->inst_count_interrupt += thr->interrupt_init;
@@ -54518,44 +56026,45 @@ void duk__coerce_effective_this_binding(duk_hthread *thr,
duk_hobject *func,
duk_idx_t idx_this) {
duk_context *ctx = (duk_context *) thr;
- duk_small_int_t strict;
+ duk_tval *tv_this;
+ duk_hobject *obj_global;
- if (func) {
- strict = DUK_HOBJECT_HAS_STRICT(func);
- } else {
+ if (func == NULL || DUK_HOBJECT_HAS_STRICT(func)) {
/* Lightfuncs are always considered strict. */
- strict = 1;
+ DUK_DDD(DUK_DDDPRINT("this binding: strict -> use directly"));
+ return;
}
- if (strict) {
- DUK_DDD(DUK_DDDPRINT("this binding: strict -> use directly"));
- } else {
- duk_tval *tv_this = duk_require_tval(ctx, idx_this);
- duk_hobject *obj_global;
-
- if (DUK_TVAL_IS_OBJECT(tv_this)) {
- DUK_DDD(DUK_DDDPRINT("this binding: non-strict, object -> use
directly"));
- } else if (DUK_TVAL_IS_LIGHTFUNC(tv_this)) {
- /* Lightfuncs are treated like objects and not coerced. */
- DUK_DDD(DUK_DDDPRINT("this binding: non-strict, lightfunc -> use
directly"));
- } else if (DUK_TVAL_IS_UNDEFINED(tv_this) || DUK_TVAL_IS_NULL(tv_this)) {
- DUK_DDD(DUK_DDDPRINT("this binding: non-strict, undefined/null -> use global
object"));
- obj_global = thr->builtins[DUK_BIDX_GLOBAL];
- if (obj_global) {
- duk_push_hobject(ctx, obj_global);
- } else {
- /*
- * This may only happen if built-ins are being "torn down".
- * This behavior is out of specification scope.
- */
- DUK_D(DUK_DPRINT("this binding: wanted to use global object, but it is NULL
-> using undefined instead"));
- duk_push_undefined(ctx);
- }
- duk_replace(ctx, idx_this);
+ /* XXX: byte offset */
+ tv_this = thr->valstack_bottom + idx_this;
+ switch (DUK_TVAL_GET_TAG(tv_this)) {
+ case DUK_TAG_OBJECT:
+ case DUK_TAG_LIGHTFUNC: /* lightfuncs are treated like objects and not coerced */
+ DUK_DDD(DUK_DDDPRINT("this binding: non-strict, object -> use
directly"));
+ break;
+ case DUK_TAG_UNDEFINED:
+ case DUK_TAG_NULL:
+ DUK_DDD(DUK_DDDPRINT("this binding: non-strict, undefined/null -> use global
object"));
+ obj_global = thr->builtins[DUK_BIDX_GLOBAL];
+ /* XXX: avoid this check somehow */
+ if (DUK_LIKELY(obj_global != NULL)) {
+ DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this)); /* no need to decref previous value
*/
+ DUK_TVAL_SET_OBJECT(tv_this, obj_global);
+ DUK_HOBJECT_INCREF(thr, obj_global);
} else {
- DUK_DDD(DUK_DDDPRINT("this binding: non-strict, not object/undefined/null ->
use ToObject(value)"));
- duk_to_object(ctx, idx_this); /* may have side effects */
+ /* This may only happen if built-ins are being "torn down".
+ * This behavior is out of specification scope.
+ */
+ DUK_D(DUK_DPRINT("this binding: wanted to use global object, but it is NULL ->
using undefined instead"));
+ DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this)); /* no need to decref previous value
*/
+ DUK_TVAL_SET_UNDEFINED(tv_this); /* nothing to incref */
}
+ break;
+ default:
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this));
+ DUK_DDD(DUK_DDDPRINT("this binding: non-strict, not object/undefined/null ->
use ToObject(value)"));
+ duk_to_object(ctx, idx_this); /* may have side effects */
+ break;
}
}
@@ -54689,11 +56198,11 @@ void duk__adjust_valstack_and_top(duk_hthread *thr, duk_idx_t
num_stack_args, du
* for errhandler calls
* DUK_CALL_FLAG_CONSTRUCTOR_CALL <--> for 'new Foo()' calls
*
- * Input stack:
+ * Input stack (thr):
*
* [ func this arg1 ... argN ]
*
- * Output stack:
+ * Output stack (thr):
*
* [ retval ] (DUK_EXEC_SUCCESS)
* [ errobj ] (DUK_EXEC_ERROR (normal error), protected call)
@@ -54705,7 +56214,7 @@ void duk__adjust_valstack_and_top(duk_hthread *thr, duk_idx_t
num_stack_args, du
* indices) cause an error to propagate out of this function. If there is
* no catchpoint for this error, the fatal error handler is called.
*
- * See 'execution.txt'.
+ * See 'execution.rst'.
*
* The allowed thread states for making a call are:
* - thr matches heap->curr_thread, and thr is already RUNNING
@@ -54717,7 +56226,7 @@ void duk__adjust_valstack_and_top(duk_hthread *thr, duk_idx_t
num_stack_args, du
* avoiding a dozen helpers with awkward plumbing.
*
* Note: setjmp() and local variables have a nasty interaction,
- * see execution.txt; non-volatile locals modified after setjmp()
+ * see execution.rst; non-volatile locals modified after setjmp()
* call are not guaranteed to keep their value.
*/
@@ -54733,9 +56242,10 @@ duk_int_t duk_handle_call(duk_hthread *thr,
duk_int_t entry_call_recursion_depth;
duk_hthread *entry_curr_thread;
duk_uint_fast8_t entry_thread_state;
+ duk_instr_t **entry_ptr_curr_pc;
volatile duk_bool_t need_setjmp;
duk_jmpbuf * volatile old_jmpbuf_ptr = NULL; /* ptr is volatile (not the target) */
- duk_idx_t idx_func; /* valstack index of 'func' and retval (relative to
entry valstack_bottom) */
+ volatile duk_idx_t idx_func; /* valstack index of 'func' and retval
(relative to entry valstack_bottom) */
duk_idx_t idx_args; /* valstack index of start of args (arg1) (relative to entry
valstack_bottom) */
duk_idx_t nargs; /* # argument registers target function wants (< 0 =>
"as is") */
duk_idx_t nregs; /* # total registers target function wants on entry (< 0
=> "as is") */
@@ -54745,7 +56255,6 @@ duk_int_t duk_handle_call(duk_hthread *thr,
duk_activation *act;
duk_hobject *env;
duk_jmpbuf our_jmpbuf;
- duk_tval tv_tmp;
duk_int_t retval = DUK_EXEC_ERROR;
duk_ret_t rc;
@@ -54768,12 +56277,19 @@ duk_int_t duk_handle_call(duk_hthread *thr,
*/
entry_valstack_bottom_index = (duk_size_t) (thr->valstack_bottom -
thr->valstack);
+#if defined(DUK_USE_PREFER_SIZE)
entry_valstack_end = (duk_size_t) (thr->valstack_end - thr->valstack);
+#else
+ DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack) ==
thr->valstack_size);
+ entry_valstack_end = thr->valstack_size;
+#endif
entry_callstack_top = thr->callstack_top;
entry_catchstack_top = thr->catchstack_top;
entry_call_recursion_depth = thr->heap->call_recursion_depth;
entry_curr_thread = thr->heap->curr_thread; /* Note: may be NULL if first call
*/
entry_thread_state = thr->state;
+ entry_ptr_curr_pc = thr->ptr_curr_pc; /* may be NULL */
+
idx_func = duk_normalize_index(ctx, -num_stack_args - 2); /* idx_func must be valid,
note: non-throwing! */
idx_args = idx_func + 2; /* idx_args is not
necessarily valid if num_stack_args == 0 (idx_args then equals top) */
@@ -54806,6 +56322,12 @@ duk_int_t duk_handle_call(duk_hthread *thr,
(void *) entry_curr_thread,
(long) entry_thread_state));
+ /* If thr->ptr_curr_pc is set, sync curr_pc to act->pc. Then NULL
+ * thr->ptr_curr_pc so that it's not accidentally used with an incorrect
+ * activation when side effects occur.
+ */
+ duk_hthread_sync_and_null_currpc(thr);
+
/* XXX: Multiple tv_func lookups are now avoided by making a local
* copy of tv_func. Another approach would be to compute an offset
* for tv_func from valstack bottom and recomputing the tv_func
@@ -54867,6 +56389,11 @@ duk_int_t duk_handle_call(duk_hthread *thr,
DUK_ASSERT(thr->callstack_top >= entry_callstack_top);
DUK_ASSERT(thr->catchstack_top >= entry_catchstack_top);
+ /* We don't need to sync back thr->curr_pc here because the
+ * bytecode executor always has a setjmp catchpoint which
+ * does that before errors propagate to here.
+ */
+
/*
* Restore previous setjmp catchpoint
*/
@@ -54897,6 +56424,9 @@ duk_int_t duk_handle_call(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("call is not protected -> clean up and rethrow"));
+ /* Restore entry thread executor curr_pc stack frame pointer. */
+ thr->ptr_curr_pc = entry_ptr_curr_pc;
+
DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */
thr->state = entry_thread_state;
DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE &&
thr->heap->curr_thread == NULL) || /* first call */
@@ -55118,7 +56648,7 @@ duk_int_t duk_handle_call(duk_hthread *thr,
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
act->prev_caller = NULL;
#endif
- act->pc = 0;
+ act->curr_pc = NULL;
#if defined(DUK_USE_DEBUGGER_SUPPORT)
act->prev_line = 0;
#endif
@@ -55197,6 +56727,7 @@ duk_int_t duk_handle_call(duk_hthread *thr,
/* [... func this arg1 ... argN envobj] */
+ act = thr->callstack + thr->callstack_top - 1;
act->lex_env = env;
act->var_env = env;
DUK_HOBJECT_INCREF(thr, env);
@@ -55261,6 +56792,9 @@ duk_int_t duk_handle_call(duk_hthread *thr,
* other invalid
*/
+ /* For native calls must be NULL so we don't sync back */
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+
if (func) {
rc = ((duk_hnativefunction *) func)->func((duk_context *) thr);
} else {
@@ -55347,6 +56881,10 @@ duk_int_t duk_handle_call(duk_hthread *thr,
* Shift to new valstack_bottom.
*/
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT(DUK_HOBJECT_HAS_COMPILEDFUNCTION(func));
+ act->curr_pc = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap,
(duk_hcompiledfunction *) func);
+
thr->valstack_bottom = thr->valstack_bottom + idx_args;
/* keep current valstack_top */
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
@@ -55368,6 +56906,8 @@ duk_int_t duk_handle_call(duk_hthread *thr,
*
*/
+ /* thr->ptr_curr_pc is set by bytecode executor early on entry */
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
DUK_DDD(DUK_DDDPRINT("entering bytecode execution"));
duk_js_execute_bytecode(thr);
DUK_DDD(DUK_DDDPRINT("returned from bytecode execution"));
@@ -55456,17 +56996,15 @@ duk_int_t duk_handle_call(duk_hthread *thr,
* runs etc capture even out-of-memory errors so nothing should
* throw here.
*/
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
-
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value2);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value2);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1); /* side effects
*/
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2); /* side effects
*/
DUK_DDD(DUK_DDDPRINT("setjmp catchpoint torn down"));
}
+ /* Restore entry thread executor curr_pc stack frame pointer. */
+ thr->ptr_curr_pc = entry_ptr_curr_pc;
+
DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */
thr->state = (duk_uint8_t) entry_thread_state;
@@ -55476,6 +57014,24 @@ duk_int_t duk_handle_call(duk_hthread *thr,
thr->heap->call_recursion_depth = entry_call_recursion_depth;
+ /* If the debugger is active we need to force an interrupt so that
+ * debugger breakpoints are rechecked. This is important for function
+ * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see
+ * GH-303. Only needed for success path, error path always causes a
+ * breakpoint recheck in the executor. It would be enough to set this
+ * only when returning to an Ecmascript activation, but setting the flag
+ * on every return should have no ill effect.
+ */
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
+ DUK_DD(DUK_DDPRINT("returning to ecmascript activation with debugger enabled,
force interrupt"));
+ DUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);
+ thr->interrupt_init -= thr->interrupt_counter;
+ thr->interrupt_counter = 0;
+ thr->heap->dbg_force_restart = 1;
+ }
+#endif
+
#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)
duk__interrupt_fixup(thr, entry_curr_thread);
#endif
@@ -55599,9 +57155,9 @@ duk_int_t duk_handle_safe_call(duk_hthread *thr,
duk_int_t entry_call_recursion_depth;
duk_hthread *entry_curr_thread;
duk_uint_fast8_t entry_thread_state;
+ duk_instr_t **entry_ptr_curr_pc;
duk_jmpbuf *old_jmpbuf_ptr = NULL;
duk_jmpbuf our_jmpbuf;
- duk_tval tv_tmp;
duk_idx_t idx_retbase;
duk_int_t retval;
duk_ret_t rc;
@@ -55616,6 +57172,7 @@ duk_int_t duk_handle_safe_call(duk_hthread *thr,
entry_call_recursion_depth = thr->heap->call_recursion_depth;
entry_curr_thread = thr->heap->curr_thread; /* Note: may be NULL if first call
*/
entry_thread_state = thr->state;
+ entry_ptr_curr_pc = thr->ptr_curr_pc; /* may be NULL */
idx_retbase = duk_get_top(ctx) - num_stack_args; /* Note: not a valid stack index if
num_stack_args == 0 */
/* Note: cannot portably debug print a function pointer, hence 'func' not
printed! */
@@ -55825,16 +57382,14 @@ duk_int_t duk_handle_safe_call(duk_hthread *thr,
* runs etc capture even out-of-memory errors so nothing should
* throw here.
*/
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp);
-
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value2);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value2);
- DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1); /* side effects
*/
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2); /* side effects
*/
DUK_DDD(DUK_DDDPRINT("setjmp catchpoint torn down"));
+ /* Restore entry thread executor curr_pc stack frame pointer. */
+ thr->ptr_curr_pc = entry_ptr_curr_pc;
+
/* XXX: because we unwind stacks above, thr->heap->curr_thread is at
* risk of pointing to an already freed thread. This was indeed the
* case in test-bug-multithread-valgrind.c, until duk_handle_call()
@@ -55853,6 +57408,10 @@ duk_int_t duk_handle_safe_call(duk_hthread *thr,
/* stack discipline consistency check */
DUK_ASSERT(duk_get_top(ctx) == idx_retbase + num_stack_rets);
+ /* A debugger forced interrupt check is not needed here, as
+ * problematic safe calls are not caused by side effects.
+ */
+
#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)
duk__interrupt_fixup(thr, entry_curr_thread);
#endif
@@ -55906,6 +57465,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
duk_activation *act;
duk_hobject *env;
duk_bool_t use_tailcall;
+ duk_instr_t **entry_ptr_curr_pc;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(ctx != NULL);
@@ -55921,7 +57481,15 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
(thr->state == DUK_HTHREAD_STATE_RUNNING &&
thr->heap->curr_thread == thr));
- /* if a tailcall:
+ /* If thr->ptr_curr_pc is set, sync curr_pc to act->pc. Then NULL
+ * thr->ptr_curr_pc so that it's not accidentally used with an incorrect
+ * activation when side effects occur. If we end up not making the
+ * call we must restore the value.
+ */
+ entry_ptr_curr_pc = thr->ptr_curr_pc;
+ duk_hthread_sync_and_null_currpc(thr);
+
+ /* if a tail call:
* - an Ecmascript activation must be on top of the callstack
* - there cannot be any active catchstack entries
*/
@@ -55991,6 +57559,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
func = duk__nonbound_func_lookup(ctx, idx_func, &num_stack_args, &tv_func,
call_flags);
if (func == NULL || !DUK_HOBJECT_IS_COMPILEDFUNCTION(func)) {
DUK_DDD(DUK_DDDPRINT("final target is a lightfunc/nativefunc, cannot do
ecma-to-ecma call"));
+ thr->ptr_curr_pc = entry_ptr_curr_pc;
return 0;
}
/* XXX: tv_func is not actually needed */
@@ -56012,7 +57581,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
/*
* Preliminary activation record and valstack manipulation.
* The concrete actions depend on whether the we're dealing
- * with a tailcall (reuse an existing activation), a resume,
+ * with a tail call (reuse an existing activation), a resume,
* or a normal call.
*
* The basic actions, in varying order, are:
@@ -56043,17 +57612,16 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
act = thr->callstack + thr->callstack_top - 1;
if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
/* See: test-bug-tailcall-preventyield-assert.c. */
- DUK_DDD(DUK_DDDPRINT("tailcall prevented by current activation having
DUK_ACT_FLAG_PREVENTYIELD"));
+ DUK_DDD(DUK_DDDPRINT("tail call prevented by current activation having
DUK_ACT_FLAG_PREVENTYIELD"));
use_tailcall = 0;
} else if (DUK_HOBJECT_HAS_NOTAIL(func)) {
- DUK_D(DUK_DPRINT("tailcall prevented by function having a notail flag"));
+ DUK_D(DUK_DPRINT("tail call prevented by function having a notail flag"));
use_tailcall = 0;
}
}
if (use_tailcall) {
duk_tval *tv1, *tv2;
- duk_tval tv_tmp;
duk_size_t cs_index;
duk_int_t i_stk; /* must be signed for loop structure */
duk_idx_t i_arg;
@@ -56065,10 +57633,10 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
* the current activation (or simulate an unwind). In particular, the
* current activation must be closed, otherwise something like
* test-bug-reduce-judofyr.js results. Also catchstack needs be unwound
- * because there may be non-error-catching label entries in valid tailcalls.
+ * because there may be non-error-catching label entries in valid tail calls.
*/
- DUK_DDD(DUK_DDDPRINT("is tailcall, reusing activation at callstack top, at index
%ld",
+ DUK_DDD(DUK_DDDPRINT("is tail call, reusing activation at callstack top, at index
%ld",
(long) (thr->callstack_top - 1)));
/* 'act' already set above */
@@ -56104,7 +57672,10 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
act->prev_caller = NULL;
#endif
- act->pc = 0; /* don't want an intermediate exposed state with invalid pc
*/
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT(DUK_HOBJECT_HAS_COMPILEDFUNCTION(func));
+ /* don't want an intermediate exposed state with invalid pc */
+ act->curr_pc = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap,
(duk_hcompiledfunction *) func);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
act->prev_line = 0;
#endif
@@ -56116,7 +57687,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
#ifdef DUK_USE_TAILCALL
-#error incorrect options: tailcalls enabled with function caller property
+#error incorrect options: tail calls enabled with function caller property
#endif
/* XXX: this doesn't actually work properly for tail calls, so
* tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
@@ -56133,7 +57704,6 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
DUK_ASSERT(DUK_ACT_GET_FUNC(act) == func); /* already updated */
DUK_ASSERT(act->var_env == NULL); /* already NULLed (by unwind) */
DUK_ASSERT(act->lex_env == NULL); /* already NULLed (by unwind) */
- DUK_ASSERT(act->pc == 0); /* already zeroed */
act->idx_bottom = entry_valstack_bottom_index; /* tail call -> reuse current
"frame" */
DUK_ASSERT(nregs >= 0);
#if 0 /* topmost activation idx_retval is considered garbage, no need to init */
@@ -56148,7 +57718,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
* [ ... this_old | (crud) func this_new arg1 ... argN ]
* --> [ ... this_new | arg1 ... argN ]
*
- * For tailcalling to work properly, the valstack bottom must not grow
+ * For tail calling to work properly, the valstack bottom must not grow
* here; otherwise crud would accumulate on the valstack.
*/
@@ -56156,10 +57726,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
tv2 = thr->valstack_bottom + idx_func + 1;
DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); /*
tv1 is -below- valstack_bottom */
DUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 <
thr->valstack_top);
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, tv2);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
for (i_arg = 0; i_arg < idx_args; i_arg++) {
/* XXX: block removal API primitive */
@@ -56173,7 +57740,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
/* [ ... this_new | arg1 ... argN ] */
} else {
- DUK_DDD(DUK_DDDPRINT("not a tailcall, pushing a new activation to callstack, to
index %ld",
+ DUK_DDD(DUK_DDDPRINT("not a tail call, pushing a new activation to callstack, to
index %ld",
(long) (thr->callstack_top)));
duk_hthread_callstack_grow(thr);
@@ -56208,7 +57775,9 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
act->prev_caller = NULL;
#endif
- act->pc = 0;
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT(DUK_HOBJECT_HAS_COMPILEDFUNCTION(func));
+ act->curr_pc = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap,
(duk_hcompiledfunction *) func);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
act->prev_line = 0;
#endif
@@ -56279,6 +57848,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
/* [... arg1 ... argN envobj] */
+ act = thr->callstack + thr->callstack_top - 1;
act->lex_env = env;
act->var_env = env;
DUK_HOBJECT_INCREF(thr, act->lex_env);
@@ -56336,7 +57906,7 @@ duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
* Recursion limits are in key functions to prevent arbitrary C recursion:
* function body parsing, statement parsing, and expression parsing.
*
- * See doc/compiler.txt for discussion on the design.
+ * See doc/compiler.rst for discussion on the design.
*
* A few typing notes:
*
@@ -56465,10 +58035,11 @@ duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx
*comp_ctx,
duk_small_uint_t flags);
DUK_LOCAL_DECL duk_reg_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
#if 0 /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__ivalue_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue
*x);
+DUK_LOCAL_DECL duk_reg_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
#endif
DUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x,
duk_int_t forced_reg);
DUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx,
duk_ivalue *x);
+DUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx,
duk_ivalue *x);
/* identifier handling */
DUK_LOCAL_DECL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx
*comp_ctx);
@@ -56491,17 +58062,22 @@ DUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_s
DUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_small_uint_t
rbp_flags);
/* convenience helpers */
+#if 0 /* unused */
DUK_LOCAL_DECL duk_reg_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
+#endif
#if 0 /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__expr_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
+DUK_LOCAL_DECL duk_reg_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
#endif
DUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags, duk_reg_t forced_reg);
DUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue
*res, duk_small_uint_t rbp_flags);
+#if 0 /* unused */
+DUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_small_uint_t rbp_flags);
+#endif
DUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
DUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
DUK_LOCAL_DECL duk_reg_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
#if 0 /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__exprtop_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue
*res, duk_small_uint_t rbp_flags);
+DUK_LOCAL_DECL duk_reg_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags);
#endif
DUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags, duk_reg_t forced_reg);
DUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_small_uint_t rbp_flags);
@@ -56551,7 +58127,7 @@ DUK_LOCAL_DECL duk_int_t
duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, d
/* XXX: actually single step levels would work just fine, clean up */
-/* binding power "levels" (see doc/compiler.txt) */
+/* binding power "levels" (see doc/compiler.rst) */
#define DUK__BP_INVALID 0 /* always terminates led() */
#define DUK__BP_EOF 2
#define DUK__BP_CLOSING 4 /* token closes expression, e.g.
')', ']' */
@@ -56738,7 +58314,7 @@ DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx,
duk_small_int_t e
* We can use either 't' or 't_nores'; the latter would not
* recognize keywords. Some keywords can be followed by a
* RegExp (e.g. "return"), so using 't' is better. This is
- * not trivial, see doc/compiler.txt.
+ * not trivial, see doc/compiler.rst.
*/
regexp = 1;
@@ -56848,7 +58424,7 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx
*comp_ctx) {
func->labelinfos_idx = entry_top + 5;
func->h_labelinfos = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, entry_top + 5);
DUK_ASSERT(func->h_labelinfos != NULL);
- DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos));
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) &&
!DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));
duk_push_array(ctx);
func->argnames_idx = entry_top + 6;
@@ -56924,9 +58500,9 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx
*comp_ctx) {
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);
if (!DUK_TVAL_IS_NUMBER(tv)) {
DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));
- DUK_TVAL_SET_UNDEFINED_UNUSED(tv);
DUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);
DUK_HSTRING_DECREF(thr, h_key);
+ /* when key is NULL, value is garbage so no need to set */
} else {
ret++;
}
@@ -58096,11 +59672,35 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx
*comp_ctx) {
* code (it is checked as it is used).
*/
#define DUK__IVAL_FLAG_ALLOW_CONST (1 << 0) /* allow a constant to be
returned */
-#define DUK__IVAL_FLAG_REQUIRE_TEMP (1 << 1) /* require a (mutable)
temporary as a result */
+#define DUK__IVAL_FLAG_REQUIRE_TEMP (1 << 1) /* require a (mutable)
temporary as a result (or a const if allowed) */
#define DUK__IVAL_FLAG_REQUIRE_SHORT (1 << 2) /* require a short (8-bit)
reg/const which fits into bytecode B/C slot */
/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(ctx,x) */
+#if 0 /* enable manually for dumping */
+#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while
(0)
+#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), (ivalue)); }
while (0)
+
+DUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {
+ DUK_D(DUK_DPRINT("ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld,
value=%!T",
+ (long) x->t, (unsigned long) x->regconst, (long)
x->valstack_idx,
+ duk_get_tval((duk_context *) comp_ctx->thr, x->valstack_idx)));
+}
+DUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
+ DUK_D(DUK_DPRINT("ivalue dump: t=%ld op=%ld "
+ "x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} "
+ "x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}",
+ (long) x->t, (long) x->op,
+ (long) x->x1.t, (unsigned long) x->x1.regconst, (long)
x->x1.valstack_idx,
+ duk_get_tval((duk_context *) comp_ctx->thr, x->x1.valstack_idx),
+ (long) x->x2.t, (unsigned long) x->x2.regconst, (long)
x->x2.valstack_idx,
+ duk_get_tval((duk_context *) comp_ctx->thr,
x->x2.valstack_idx)));
+}
+#else
+#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)
+#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)
+#endif
+
DUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec
*dst) {
duk_context *ctx = (duk_context *) comp_ctx->thr;
@@ -58336,6 +59936,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx
*comp_ctx,
duk_double_t dval;
duk_int32_t ival;
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
dval = DUK_TVAL_GET_NUMBER(tv);
@@ -58367,26 +59968,34 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx
*comp_ctx,
} /* end switch */
}
case DUK_ISPEC_REGCONST: {
- if ((x->regconst & DUK__CONST_MARKER) && !(flags &
DUK__IVAL_FLAG_ALLOW_CONST)) {
- duk_reg_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, (duk_regconst_t) dest, x->regconst);
- return (duk_regconst_t) dest;
- } else {
- if (forced_reg >= 0) {
- if (x->regconst != (duk_regconst_t) forced_reg) {
- duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);
- }
- return (duk_regconst_t) forced_reg;
+ if (forced_reg >= 0) {
+ if (x->regconst & DUK__CONST_MARKER) {
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);
+ } else if (x->regconst != (duk_regconst_t) forced_reg) {
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);
} else {
- if ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISTEMP(comp_ctx,
x->regconst)) {
- duk_reg_t dest = DUK__ALLOCTEMP(comp_ctx);
- duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, (duk_regconst_t) dest, x->regconst);
- return (duk_regconst_t) dest;
- } else {
- return x->regconst;
- }
+ ; /* already in correct reg */
}
+ return (duk_regconst_t) forced_reg;
}
+
+ DUK_ASSERT(forced_reg < 0);
+ if (x->regconst & DUK__CONST_MARKER) {
+ if (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {
+ duk_reg_t dest = DUK__ALLOCTEMP(comp_ctx);
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, (duk_regconst_t) dest, x->regconst);
+ return (duk_regconst_t) dest;
+ }
+ return x->regconst;
+ }
+
+ DUK_ASSERT(forced_reg < 0 && !(x->regconst & DUK__CONST_MARKER));
+ if ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISTEMP(comp_ctx,
x->regconst)) {
+ duk_reg_t dest = DUK__ALLOCTEMP(comp_ctx);
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, (duk_regconst_t) dest, x->regconst);
+ return (duk_regconst_t) dest;
+ }
+ return x->regconst;
}
default: {
break;
@@ -58685,7 +60294,7 @@ DUK_LOCAL duk_reg_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx,
duk_ivalue *x)
}
#if 0 /* unused */
-DUK_LOCAL duk_reg_t duk__ivalue_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
+DUK_LOCAL duk_reg_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
return duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP
/*flags*/);
}
#endif
@@ -58699,6 +60308,10 @@ DUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx
*comp_ctx, duk_
return duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST
/*flags*/);
}
+DUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue
*x) {
+ return duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST |
DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);
+}
+
/* The issues below can be solved with better flags */
/* XXX: many operations actually want toforcedtemp() -- brand new temp? */
@@ -59663,7 +61276,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx,
duk_ivalue *res) {
* such that parsing ends at an LPAREN (CallExpression) but not at
* a PERIOD or LBRACKET (MemberExpression).
*
- * See doc/compiler.txt for discussion on the parsing approach,
+ * See doc/compiler.rst for discussion on the parsing approach,
* and testcases/test-dev-new.js for a bunch of documented tests.
*/
@@ -60512,7 +62125,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx,
duk_ivalue *left, duk_i
* Truthval determines when to skip right-hand-side.
* For logical AND truthval=1, for logical OR truthval=0.
*
- * See doc/compiler.txt for discussion on compiling logical
+ * See doc/compiler.rst for discussion on compiling logical
* AND and OR expressions. The approach here is very simplistic,
* generating extra jumps and multiple evaluations of truth values,
* but generates code on-the-fly with only local back-patching.
@@ -60558,11 +62171,21 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx,
duk_ivalue *left, duk_i
* Syntactically valid left-hand-side forms which are not accepted as
* left-hand-side values (e.g. as in "f() = 1") must NOT cause a
* SyntaxError, but rather a run-time ReferenceError.
+ *
+ * Assignment expression value is conceptually the LHS/RHS value
+ * copied into a fresh temporary so that it won't change even if
+ * LHS/RHS values change (e.g. when they're identifiers). Doing this
+ * concretely produces inefficient bytecode, so we try to avoid the
+ * extra temporary for some known-to-be-safe cases. Currently the
+ * only safe case we detect is a "top level assignment", for example
+ * "x = y + z;", where the assignment expression value is ignored.
+ * See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.
*/
{
duk_small_uint_t args_op = args >> 8;
duk_small_uint_t args_rbp = args & 0xff;
+ duk_bool_t toplevel_assign;
/* XXX: here we need to know if 'left' is left-hand-side compatible.
* That information is no longer available from current expr parsing
@@ -60570,44 +62193,89 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx,
duk_ivalue *left, duk_i
* some other means.
*/
+ /* A top-level assignment is e.g. "x = y;". For these it's safe
+ * to use the RHS as-is as the expression value, even if the RHS
+ * is a reg-bound identifier. The RHS ('res') is right associative
+ * so it has consumed all other assignment level operations; the
+ * only relevant lower binding power construct is comma operator
+ * which will ignore the expression value provided here.
+ */
+ toplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before
*/
+ comp_ctx->curr_func.led_count == 1); /* one operator (= assign)
*/
+ DUK_DDD(DUK_DDDPRINT("assignment: nud_count=%ld, led_count=%ld,
toplevel_assign=%ld",
+ (long) comp_ctx->curr_func.nud_count,
+ (long) comp_ctx->curr_func.led_count,
+ (long) toplevel_assign));
+
if (left->t == DUK_IVAL_VAR) {
duk_hstring *h_varname;
duk_reg_t reg_varbind;
duk_regconst_t rc_varname;
- duk_regconst_t rc_res;
- duk_reg_t reg_temp;
- /* already in fluly evaluated form */
- DUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE);
+ DUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE); /* LHS is already side effect free */
- duk__expr_toreg(comp_ctx, res, args_rbp /*rbp_flags*/);
- DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t ==
DUK_ISPEC_REGCONST);
+ /* Keep the RHS as an unresolved ivalue for now, so it
+ * can be a plain value or a unary/binary operation here.
+ * We resolve it before finishing but doing it later allows
+ * better bytecode in some cases.
+ */
+ duk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);
h_varname = duk_get_hstring(ctx, left->x1.valstack_idx);
DUK_ASSERT(h_varname != NULL);
-
- /* E5 Section 11.13.1 (and others for other assignments), step 4 */
if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {
+ /* E5 Section 11.13.1 (and others for other assignments), step 4 */
goto syntax_error_lvalue;
}
-
duk_dup(ctx, left->x1.valstack_idx);
(void) duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname);
- DUK_DDD(DUK_DDDPRINT("assign to '%!O' -> reg_varbind=%ld,
rc_varname=%ld",
- (duk_heaphdr *) h_varname, (long) reg_varbind, (long)
rc_varname));
-
if (args_op == DUK_OP_NONE) {
- rc_res = res->x1.regconst;
+ if (toplevel_assign) {
+ /* Any 'res' will do. */
+ DUK_DDD(DUK_DDDPRINT("plain assignment, toplevel assign, use as is"));
+ } else {
+ /* 'res' must be a plain ivalue, and not register-bound variable. */
+ DUK_DDD(DUK_DDDPRINT("plain assignment, not toplevel assign, ensure not a
reg-bound identifier"));
+ if (res->t != DUK_IVAL_PLAIN || (res->x1.t == DUK_ISPEC_REGCONST &&
+ (res->x1.regconst & DUK__CONST_MARKER) == 0
&&
+ !DUK__ISTEMP(comp_ctx, res->x1.regconst))) {
+ duk__ivalue_totempconst(comp_ctx, res);
+ }
+ }
} else {
- reg_temp = DUK__ALLOCTEMP(comp_ctx);
+ duk__ivalue_toregconst(comp_ctx, res);
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t ==
DUK_ISPEC_REGCONST);
+
if (reg_varbind >= 0) {
+ duk_reg_t reg_res;
+
+ if (toplevel_assign) {
+ /* 'reg_varbind' is the operation result and can also
+ * become the expression value for top level assignments
+ * such as: "var x; x += y;".
+ */
+ reg_res = reg_varbind;
+ } else {
+ /* Not safe to use 'reg_varbind' as assignment expression
+ * value, so go through a temp.
+ */
+ reg_res = DUK__ALLOCTEMP(comp_ctx);
+ }
+
duk__emit_a_b_c(comp_ctx,
args_op,
- (duk_regconst_t) reg_temp,
+ (duk_regconst_t) reg_res,
(duk_regconst_t) reg_varbind,
res->x1.regconst);
+ res->x1.regconst = (duk_regconst_t) reg_res;
} else {
+ /* When LHS is not register bound, always go through a
+ * temporary. No optimization for top level assignment.
+ */
+ duk_reg_t reg_temp;
+ reg_temp = DUK__ALLOCTEMP(comp_ctx);
+
duk__emit_a_bc(comp_ctx,
DUK_OP_GETVAR,
(duk_regconst_t) reg_temp,
@@ -60617,40 +62285,57 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx,
duk_ivalue *left, duk_i
(duk_regconst_t) reg_temp,
(duk_regconst_t) reg_temp,
res->x1.regconst);
+ res->x1.regconst = (duk_regconst_t) reg_temp;
}
- rc_res = (duk_regconst_t) reg_temp;
+
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t ==
DUK_ISPEC_REGCONST);
}
+ /* At this point 'res' holds the potential expression value.
+ * It can be basically any ivalue here, including a reg-bound
+ * identifier (if code above deems it safe) or a unary/binary
+ * operation. Operations must be resolved to a side effect free
+ * plain value, and the side effects must happen exactly once.
+ */
+
if (reg_varbind >= 0) {
- duk__emit_a_bc(comp_ctx,
- DUK_OP_LDREG,
- (duk_regconst_t) reg_varbind,
- rc_res);
+ if (res->t != DUK_IVAL_PLAIN) {
+ /* Resolve 'res' directly into the LHS binding, and use
+ * that as the expression value if safe. If not safe,
+ * resolve to a temp/const and copy to LHS.
+ */
+ if (toplevel_assign) {
+ duk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t) reg_varbind);
+ } else {
+ duk__ivalue_totempconst(comp_ctx, res);
+ duk__copy_ivalue(comp_ctx, res, left); /* use 'left' as a temp */
+ duk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);
+ }
+ } else {
+ /* Use 'res' as the expression value (it's side effect
+ * free and may be a plain value, a register, or a
+ * constant) and write it to the LHS binding too.
+ */
+ duk__copy_ivalue(comp_ctx, res, left); /* use 'left' as a temp */
+ duk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);
+ }
} else {
- /* Only a reg fits into 'A' and reg_res may be a const in
- * straight assignment.
+ /* Only a reg fits into 'A' so coerce 'res' into a register
+ * for PUTVAR.
*
* XXX: here the current A/B/C split is suboptimal: we could
* just use 9 bits for reg_res (and support constants) and 17
* instead of 18 bits for the varname const index.
*/
- if (DUK__ISCONST(comp_ctx, rc_res)) {
- reg_temp = DUK__ALLOCTEMP(comp_ctx);
- duk__emit_a_bc(comp_ctx,
- DUK_OP_LDCONST,
- (duk_regconst_t) reg_temp,
- rc_res);
- rc_res = (duk_regconst_t) reg_temp;
- }
+
+ duk__ivalue_toreg(comp_ctx, res);
duk__emit_a_bc(comp_ctx,
DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,
- rc_res,
+ res->x1.regconst,
rc_varname);
}
- res->t = DUK_IVAL_PLAIN;
- res->x1.t = DUK_ISPEC_REGCONST;
- res->x1.regconst = rc_res;
+ /* 'res' contains expression value */
} else if (left->t == DUK_IVAL_PROP) {
/* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> no check
*/
duk_reg_t reg_obj;
@@ -60964,15 +62649,17 @@ DUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_sma
* Each helper needs at least 2-3 calls to make it worth while to wrap.
*/
+#if 0 /* unused */
DUK_LOCAL duk_reg_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
duk__expr(comp_ctx, res, rbp_flags);
return duk__ivalue_toreg(comp_ctx, res);
}
+#endif
#if 0 /* unused */
-DUK_LOCAL duk_reg_t duk__expr_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
+DUK_LOCAL duk_reg_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
duk__expr(comp_ctx, res, rbp_flags);
- return duk__ivalue_totempreg(comp_ctx, res);
+ return duk__ivalue_totemp(comp_ctx, res);
}
#endif
@@ -60987,6 +62674,13 @@ DUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx
*comp_ctx, duk_iv
return duk__ivalue_toregconst(comp_ctx, res);
}
+#if 0 /* unused */
+DUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue
*res, duk_small_uint_t rbp_flags) {
+ duk__expr(comp_ctx, res, rbp_flags);
+ return duk__ivalue_totempconst(comp_ctx, res);
+}
+#endif
+
DUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
duk__expr(comp_ctx, res, rbp_flags);
duk__ivalue_toplain(comp_ctx, res);
@@ -61003,9 +62697,9 @@ DUK_LOCAL duk_reg_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx,
duk_ivalue *r
}
#if 0 /* unused */
-DUK_LOCAL duk_reg_t duk__exprtop_totempreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
+DUK_LOCAL duk_reg_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_small_uint_t rbp_flags) {
duk__exprtop(comp_ctx, res, rbp_flags);
- return duk__ivalue_totempreg(comp_ctx, res);
+ return duk__ivalue_totemp(comp_ctx, res);
}
#endif
@@ -61172,7 +62866,7 @@ DUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res)
DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t
pc_label_site) {
duk_hthread *thr = comp_ctx->thr;
duk_context *ctx = (duk_context *) thr;
- duk_int_t pc_v34_lhs; /* start variant 3/4 left-hand-side code (L1 in
doc/compiler.txt example) */
+ duk_int_t pc_v34_lhs; /* start variant 3/4 left-hand-side code (L1 in
doc/compiler.rst example) */
duk_reg_t temp_reset; /* knock back "next temp" to this whenever possible
*/
duk_reg_t reg_temps; /* preallocated temporaries (2) for variants 3 and 4 */
@@ -61199,7 +62893,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res,
* Parsing these without arbitrary lookahead or backtracking is relatively
* tricky but we manage to do so for now.
*
- * See doc/compiler.txt for a detailed discussion of control flow
+ * See doc/compiler.rst for a detailed discussion of control flow
* issues, evaluation order issues, etc.
*/
@@ -61426,7 +63120,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res,
*
* Variables set before entering here:
*
- * pc_v34_lhs: insert a "JUMP L2" here (see doc/compiler.txt example).
+ * pc_v34_lhs: insert a "JUMP L2" here (see doc/compiler.rst example).
* reg_temps + 0: iteration target value (written to LHS)
* reg_temps + 1: enumerator object
*/
@@ -61441,7 +63135,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res,
/* First we need to insert a jump in the middle of previously
* emitted code to get the control flow right. No jumps can
- * cross the position where the jump is inserted. See doc/compiler.txt
+ * cross the position where the jump is inserted. See doc/compiler.rst
* for discussion on the intricacies of control flow and side effects
* for variants 3 and 4.
*/
@@ -61556,7 +63250,7 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *re
* only process the first match before switching to a "propagation" mode
* where case values are no longer evaluated
*
- * See E5 Section 12.11. Also see doc/compiler.txt for compilation
+ * See E5 Section 12.11. Also see doc/compiler.rst for compilation
* discussion.
*/
@@ -61899,12 +63593,6 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *re
DUK_ERROR(thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_INVALID_RETURN);
}
- /* Use a fast return when possible. A fast return does not cause a longjmp()
- * unnecessarily. A fast return can be done when no TCF catchers are active
- * (this includes 'try' and 'with' statements). Active label catches do
not
- * prevent a fast return; they're unwound on return automatically.
- */
-
ret_flags = 0;
if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || /* explicit semi follows */
@@ -61926,10 +63614,10 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx
*comp_ctx, duk_ivalue *re
pc_after_expr = duk__get_current_pc(comp_ctx);
/* Tail call check: if last opcode emitted was CALL(I), and
- * the context allows it, change the CALL(I) to a tailcall.
- * This doesn't guarantee that a tailcall will be allowed at
+ * the context allows it, change the CALL(I) to a tail call.
+ * This doesn't guarantee that a tail call will be allowed at
* runtime, so the RETURN must still be emitted. (Duktape
- * 0.10.0 avoided this and simulated a RETURN if a tailcall
+ * 0.10.0 avoided this and simulated a RETURN if a tail call
* couldn't be used at runtime; but this didn't work
* correctly with a thread yield/resume, see
* test-bug-tailcall-thread-yield-resume.js for discussion.)
@@ -61940,7 +63628,7 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *re
* { return 1; }), 2' the last opcode emitted is CALL (no
* bytecode is emitted for '2') but 'rc_val' indicates
* constant '2'. Similarly if '2' is replaced by a register
- * bound variable, no opcodes are emitted but tailcall would
+ * bound variable, no opcodes are emitted but tail call would
* be incorrect.
*
* This is tricky and easy to get wrong. It would be best to
@@ -61985,21 +63673,6 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *re
ret_flags = DUK_BC_RETURN_FLAG_HAVE_RETVAL;
}
- /* XXX: For now, "fast returns" are disabled. The compiler doesn't track
- * label site depth so when it emits a fast return, it doesn't know whether
- * label sites exist or not. Label sites are emitted for e.g. for loops,
- * so it's probably quite relevant to handle them in the executor's fast
- * return handler.
- */
-#if 0
- if (comp_ctx->curr_func.catch_depth == 0) {
- DUK_DDD(DUK_DDDPRINT("fast return allowed -> use fast return"));
- ret_flags |= DUK_BC_RETURN_FLAG_FAST;
- } else {
- DUK_DDD(DUK_DDDPRINT("fast return not allowed -> use slow return"));
- }
-#endif
-
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) ret_flags /*flags*/,
@@ -62039,7 +63712,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res)
/*
* See the following documentation for discussion:
*
- * doc/execution.txt: control flow details
+ * doc/execution.rst: control flow details
*
* Try, catch, and finally "parts" are Blocks, not Statements, so
* they must always be delimited by curly braces. This is unlike e.g.
@@ -62491,7 +64164,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_
*
*
https://bugs.ecmascript.org/show_bug.cgi?id=8
*
- * See doc/compiler.txt for details.
+ * See doc/compiler.rst for details.
*/
DUK_DDD(DUK_DDDPRINT("do statement"));
DUK_ASSERT(label_id >= 0);
@@ -62580,13 +64253,13 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx,
duk_ivalue *res, duk_
break;
}
case DUK_TOK_DEBUGGER: {
+ duk__advance(comp_ctx);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_DDD(DUK_DDDPRINT("debugger statement: debugging enabled, emit debugger
opcode"));
duk__emit_extraop_only(comp_ctx, DUK_EXTRAOP_DEBUGGER);
#else
DUK_DDD(DUK_DDDPRINT("debugger statement: ignored"));
#endif
- duk__advance(comp_ctx);
stmt_flags = DUK__HAS_TERM;
break;
}
@@ -63477,16 +65150,16 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx,
duk_bool_t expec
* (directly or via a jump)
*/
- DUK_ASSERT(comp_ctx->curr_func.catch_depth == 0); /* fast returns are always OK here
*/
+ DUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);
if (reg_stmt_value >= 0) {
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
- (duk_regconst_t) (DUK_BC_RETURN_FLAG_HAVE_RETVAL |
DUK_BC_RETURN_FLAG_FAST) /*flags*/,
+ (duk_regconst_t) DUK_BC_RETURN_FLAG_HAVE_RETVAL /*flags*/,
(duk_regconst_t) reg_stmt_value /*reg*/);
} else {
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
- (duk_regconst_t) DUK_BC_RETURN_FLAG_FAST /*flags*/,
+ (duk_regconst_t) 0 /*flags*/,
(duk_regconst_t) 0 /*reg(ignored)*/);
}
@@ -63859,7 +65532,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx) {
comp_ctx->tok12_idx = entry_top + 2;
comp_ctx->tok21_idx = entry_top + 3;
comp_ctx->tok22_idx = entry_top + 4;
- comp_ctx->recursion_limit = DUK_COMPILER_RECURSION_LIMIT;
+ comp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT;
/* comp_ctx->lex has been pre-initialized by caller: it has been
* zeroed and input/input_length has been set.
@@ -63871,7 +65544,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx) {
comp_ctx->lex.buf_idx = entry_top + 0;
comp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, entry_top + 0);
DUK_ASSERT(comp_ctx->lex.buf != NULL);
- DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf));
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) &&
!DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf));
comp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT;
lex_pt->offset = 0;
@@ -64015,22 +65688,24 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const
duk_uint8_t *src_buffer
/* include removed: duk_internal.h */
/*
- * Local declarations
+ * Local declarations.
*/
-DUK_LOCAL_DECL void duk__reconfig_valstack(duk_hthread *thr, duk_size_t act_idx,
duk_small_uint_t retval_count);
+DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_size_t
entry_callstack_top);
/*
* Arithmetic, binary, and logical helpers.
*
* Note: there is no opcode for logical AND or logical OR; this is on
* purpose, because the evalution order semantics for them make such
- * opcodes pretty pointless (short circuiting means they are most
- * comfortably implemented as jumps). However, a logical NOT opcode
+ * opcodes pretty pointless: short circuiting means they are most
+ * comfortably implemented as jumps. However, a logical NOT opcode
* is useful.
*
* Note: careful with duk_tval pointers here: they are potentially
- * invalidated by any DECREF and almost any API call.
+ * invalidated by any DECREF and almost any API call. It's still
+ * preferable to work without making a copy but that's not always
+ * possible.
*/
DUK_LOCAL duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {
@@ -64080,7 +65755,6 @@ DUK_LOCAL void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x,
duk_tval *tv_
if (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {
duk_int64_t v1, v2, v3;
duk_int32_t v3_hi;
- duk_tval tv_tmp;
duk_tval *tv_z;
/* Input values are signed 48-bit so we can detect overflow
@@ -64093,10 +65767,7 @@ DUK_LOCAL void duk__vm_arith_add(duk_hthread *thr, duk_tval
*tv_x, duk_tval *tv_
v3_hi = (duk_int32_t) (v3 >> 32);
if (DUK_LIKELY(v3_hi >= -0x8000LL && v3_hi <= 0x7fffLL)) {
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_FASTINT(tv_z, v3);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */
return;
} else {
/* overflow, fall through */
@@ -64106,7 +65777,6 @@ DUK_LOCAL void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x,
duk_tval *tv_
#endif /* DUK_USE_FASTINT */
if (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {
- duk_tval tv_tmp;
duk_tval *tv_z;
du.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);
@@ -64114,10 +65784,7 @@ DUK_LOCAL void duk__vm_arith_add(duk_hthread *thr, duk_tval
*tv_x, duk_tval *tv_
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_NUMBER(tv_z, du.d);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */
return;
}
@@ -64170,7 +65837,6 @@ DUK_LOCAL void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval
*tv_x, duk_tva
*/
duk_context *ctx = (duk_context *) thr;
- duk_tval tv_tmp;
duk_tval *tv_z;
duk_double_t d1, d2;
duk_double_union du;
@@ -64247,10 +65913,7 @@ DUK_LOCAL void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval
*tv_x, duk_tva
v3_hi = (duk_int32_t) (v3 >> 32);
if (DUK_LIKELY(v3_hi >= -0x8000LL && v3_hi <= 0x7fffLL)) {
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_FASTINT(tv_z, v3);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */
return;
}
/* fall through if overflow etc */
@@ -64303,10 +65966,7 @@ DUK_LOCAL void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval
*tv_x, duk_tva
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_NUMBER(tv_z, du.d);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */
}
DUK_LOCAL void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval
*tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {
@@ -64321,7 +65981,6 @@ DUK_LOCAL void duk__vm_bitwise_binary_op(duk_hthread *thr,
duk_tval *tv_x, duk_t
*/
duk_context *ctx = (duk_context *) thr;
- duk_tval tv_tmp;
duk_tval *tv_z;
duk_int32_t i1, i2, i3;
duk_uint32_t u1, u2, u3;
@@ -64409,15 +66068,14 @@ DUK_LOCAL void duk__vm_bitwise_binary_op(duk_hthread *thr,
duk_tval *tv_x, duk_t
#if defined(DUK_USE_FASTINT)
/* Result is always fastint compatible. */
- /* XXX: set 32-bit result (but must handle signed and unsigned) */
+ /* XXX: Set 32-bit result (but must then handle signed and
+ * unsigned results separately).
+ */
fi3 = (duk_int64_t) i3;
fastint_result_set:
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_FASTINT(tv_z, fi3);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3); /* side effects */
#else
d3 = (duk_double_t) i3;
@@ -64426,10 +66084,7 @@ DUK_LOCAL void duk__vm_bitwise_binary_op(duk_hthread *thr,
duk_tval *tv_x, duk_t
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d3); /* always normalized */
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_NUMBER(tv_z, d3);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3); /* side effects */
#endif
}
@@ -64510,7 +66165,6 @@ DUK_LOCAL void duk__vm_bitwise_not(duk_hthread *thr, duk_tval
*tv_x, duk_small_u
*/
duk_context *ctx = (duk_context *) thr;
- duk_tval tv_tmp;
duk_tval *tv_z;
duk_int32_t i1, i2;
#if !defined(DUK_USE_FASTINT)
@@ -64540,10 +66194,7 @@ DUK_LOCAL void duk__vm_bitwise_not(duk_hthread *thr, duk_tval
*tv_x, duk_small_u
#if defined(DUK_USE_FASTINT)
/* Result is always fastint compatible. */
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_FASTINT_I32(tv_z, i2);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_FASTINT_I32_UPDREF(thr, tv_z, i2); /* side effects */
#else
d2 = (duk_double_t) i2;
@@ -64551,10 +66202,7 @@ DUK_LOCAL void duk__vm_bitwise_not(duk_hthread *thr, duk_tval
*tv_x, duk_small_u
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2); /* always normalized */
tv_z = thr->valstack_bottom + idx_z;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_NUMBER(tv_z, d2);
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_z)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d2); /* side effects */
#endif
}
@@ -64563,7 +66211,6 @@ DUK_LOCAL void duk__vm_logical_not(duk_hthread *thr, duk_tval
*tv_x, duk_tval *t
* E5 Section 11.4.9
*/
- duk_tval tv_tmp;
duk_bool_t res;
DUK_ASSERT(thr != NULL);
@@ -64579,37 +66226,35 @@ DUK_LOCAL void duk__vm_logical_not(duk_hthread *thr, duk_tval
*tv_x, duk_tval *t
res = duk_js_toboolean(tv_x); /* does not modify tv_x */
DUK_ASSERT(res == 0 || res == 1);
res ^= 1;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_z);
- DUK_TVAL_SET_BOOLEAN(tv_z, res); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv_z, res); /* side effects */
}
/*
- * Longjmp handler for the bytecode executor (and a bunch of static
- * helpers for it).
+ * Longjmp and other control flow transfer for the bytecode executor.
*
- * Any type of longjmp() can be caught here, including intra-function
- * longjmp()s like 'break', 'continue', (slow) 'return',
'yield', etc.
+ * The longjmp handler can handle all longjmp types: error, yield, and
+ * resume (pseudotypes are never actually thrown).
*
- * Error policy: should not ordinarily throw errors. Errors thrown
- * will bubble outwards.
- *
- * Returns:
- * 0 restart execution
- * 1 bytecode executor finished
- * 2 rethrow longjmp
+ * Error policy for longjmp: should not ordinarily throw errors; if errors
+ * occur (e.g. due to out-of-memory) they bubble outwards rather than being
+ * handled recursively.
*/
-/* XXX: duk_api operations for cross-thread reg manipulation? */
-/* XXX: post-condition: value stack must be correct; for ecmascript functions, clamped to
'nregs' */
-
#define DUK__LONGJMP_RESTART 0 /* state updated, restart bytecode execution */
-#define DUK__LONGJMP_FINISHED 1 /* exit bytecode executor with return value */
-#define DUK__LONGJMP_RETHROW 2 /* exit bytecode executor by rethrowing an error to
caller */
+#define DUK__LONGJMP_RETHROW 1 /* exit bytecode executor by rethrowing an error to
caller */
+
+#define DUK__RETHAND_RESTART 0 /* state updated, restart bytecode execution */
+#define DUK__RETHAND_FINISHED 1 /* exit bytecode execution with return value */
+
+/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting
+ * top are combined into one pass.
+ */
-/* only called when act_idx points to an Ecmascript function */
-DUK_LOCAL void duk__reconfig_valstack(duk_hthread *thr, duk_size_t act_idx,
duk_small_uint_t retval_count) {
+/* Reconfigure value stack for return to an Ecmascript function at 'act_idx'. */
+DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr, duk_size_t act_idx)
{
+ duk_activation *act;
duk_hcompiledfunction *h_func;
+ duk_idx_t clamp_top;
DUK_ASSERT(thr != NULL);
DUK_ASSERT_DISABLE(act_idx >= 0); /* unsigned */
@@ -64617,91 +66262,109 @@ DUK_LOCAL void duk__reconfig_valstack(duk_hthread *thr,
duk_size_t act_idx, duk_
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack +
act_idx)));
DUK_ASSERT_DISABLE(thr->callstack[act_idx].idx_retval >= 0); /* unsigned */
- thr->valstack_bottom = thr->valstack + thr->callstack[act_idx].idx_bottom;
-
- /* clamp so that retval is at the top (retval_count == 1) or register just before
- * intended retval is at the top (retval_count == 0, happens e.g. with
'finally').
+ /* Clamp so that values at 'clamp_top' and above are wiped and won't
+ * retain reachable garbage. Then extend to 'nregs' because we're
+ * returning to an Ecmascript function.
*/
- duk_set_top((duk_context *) thr,
- (duk_idx_t) (thr->callstack[act_idx].idx_retval -
- thr->callstack[act_idx].idx_bottom +
- retval_count));
- /*
- * When returning to an Ecmascript function, extend the valstack
- * top to 'nregs' always.
- */
+ act = thr->callstack + act_idx;
+ h_func = (duk_hcompiledfunction *) DUK_ACT_GET_FUNC(act);
- h_func = (duk_hcompiledfunction *) DUK_ACT_GET_FUNC(thr->callstack + act_idx);
+ thr->valstack_bottom = thr->valstack + act->idx_bottom;
+ DUK_ASSERT(act->idx_retval >= act->idx_bottom);
+ clamp_top = (duk_idx_t) (act->idx_retval - act->idx_bottom + 1); /* +1 = one
retval */
+ duk_set_top((duk_context *) thr, clamp_top);
+ act = NULL;
(void) duk_valstack_resize_raw((duk_context *) thr,
- (thr->valstack_bottom - thr->valstack) + /*
bottom of current func */
- h_func->nregs + /* reg
count */
- DUK_VALSTACK_INTERNAL_EXTRA, /* + spare
*/
- DUK_VSRESIZE_FLAG_SHRINK | /* flags
*/
+ (thr->valstack_bottom - thr->valstack) + /* bottom
of current func */
+ h_func->nregs + /* reg count
*/
+ DUK_VALSTACK_INTERNAL_EXTRA, /* + spare */
+ DUK_VSRESIZE_FLAG_SHRINK | /* flags */
0 /* no compact */ |
DUK_VSRESIZE_FLAG_THROW);
duk_set_top((duk_context *) thr, h_func->nregs);
}
-DUK_LOCAL void duk__handle_catch_or_finally(duk_hthread *thr, duk_size_t cat_idx,
duk_bool_t is_finally) {
- duk_context *ctx = (duk_context *) thr;
- duk_tval tv_tmp;
- duk_tval *tv1;
+DUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_size_t act_idx,
duk_size_t cat_idx) {
+ duk_activation *act;
+ duk_catcher *cat;
+ duk_hcompiledfunction *h_func;
+ duk_idx_t clamp_top;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_DISABLE(act_idx >= 0); /* unsigned */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack + act_idx) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack +
act_idx)));
+ DUK_ASSERT_DISABLE(thr->callstack[act_idx].idx_retval >= 0); /* unsigned */
- DUK_DDD(DUK_DDDPRINT("handling catch/finally, cat_idx=%ld, is_finally=%ld",
- (long) cat_idx, (long) is_finally));
+ act = thr->callstack + act_idx;
+ cat = thr->catchstack + cat_idx;
+ h_func = (duk_hcompiledfunction *) DUK_ACT_GET_FUNC(act);
- /*
- * Set caught value and longjmp type to catcher regs.
- */
+ thr->valstack_bottom = thr->valstack + act->idx_bottom;
+ DUK_ASSERT(cat->idx_base >= act->idx_bottom);
+ clamp_top = (duk_idx_t) (cat->idx_base - act->idx_bottom + 2); /* +2 = catcher
value, catcher lj_type */
+ duk_set_top((duk_context *) thr, clamp_top);
+ act = NULL;
+ cat = NULL;
- DUK_DDD(DUK_DDDPRINT("writing catch registers: idx_base=%ld -> %!T,
idx_base+1=%ld -> %!T",
- (long) thr->catchstack[cat_idx].idx_base,
- (duk_tval *) &thr->heap->lj.value1,
- (long) (thr->catchstack[cat_idx].idx_base + 1),
- (duk_tval *) &thr->heap->lj.value2));
+ (void) duk_valstack_resize_raw((duk_context *) thr,
+ (thr->valstack_bottom - thr->valstack) + /* bottom
of current func */
+ h_func->nregs + /* reg count
*/
+ DUK_VALSTACK_INTERNAL_EXTRA, /* + spare */
+ DUK_VSRESIZE_FLAG_SHRINK | /* flags */
+ 0 /* no compact */ |
+ DUK_VSRESIZE_FLAG_THROW);
+
+ duk_set_top((duk_context *) thr, h_func->nregs);
+}
+
+/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type. */
+DUK_LOCAL void duk__set_catcher_regs(duk_hthread *thr, duk_size_t cat_idx, duk_tval
*tv_val_unstable, duk_small_uint_t lj_type) {
+ duk_tval *tv1;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(tv_val_unstable != NULL);
tv1 = thr->valstack + thr->catchstack[cat_idx].idx_base;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, &thr->heap->lj.value1);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_ASSERT(tv1 < thr->valstack_top);
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */
tv1 = thr->valstack + thr->catchstack[cat_idx].idx_base + 1;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_NUMBER(tv1, (duk_double_t) thr->heap->lj.type); /* XXX: set int */
- DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv1)); /* no need to incref */
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_ASSERT(tv1 < thr->valstack_top);
- /*
- * Unwind catchstack and callstack.
- *
- * The 'cat_idx' catcher is always kept, even when executing finally.
- */
+#if defined(DUK_USE_FASTINT)
+ DUK_TVAL_SET_FASTINT_U32_UPDREF(thr, tv1, (duk_uint32_t) lj_type); /* side effects */
+#else
+ DUK_TVAL_SET_NUMBER_UPDREF(thr, tv1, (duk_double_t) lj_type); /* side effects */
+#endif
+}
+
+DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_size_t cat_idx, duk_tval
*tv_val_unstable, duk_small_uint_t lj_type) {
+ duk_context *ctx;
+ duk_activation *act;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(tv_val_unstable != NULL);
+ ctx = (duk_context *) thr;
+
+ duk__set_catcher_regs(thr, cat_idx, tv_val_unstable, lj_type);
duk_hthread_catchstack_unwind(thr, cat_idx + 1);
duk_hthread_callstack_unwind(thr, thr->catchstack[cat_idx].callstack_index + 1);
- /*
- * Reconfigure valstack to 'nregs' (this is always the case for
- * Ecmascript functions).
- */
-
DUK_ASSERT(thr->callstack_top >= 1);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack + thr->callstack_top - 1) != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack +
thr->callstack_top - 1)));
- thr->valstack_bottom = thr->valstack + (thr->callstack + thr->callstack_top
- 1)->idx_bottom;
- duk_set_top((duk_context *) thr, ((duk_hcompiledfunction *)
DUK_ACT_GET_FUNC(thr->callstack + thr->callstack_top - 1))->nregs);
-
- /*
- * Reset PC: resume execution from catch or finally jump slot.
- */
+ duk__reconfig_valstack_ecma_catcher(thr, thr->callstack_top - 1, cat_idx);
- (thr->callstack + thr->callstack_top - 1)->pc =
- thr->catchstack[cat_idx].pc_base + (is_finally ? 1 : 0);
+ DUK_ASSERT(thr->callstack_top >= 1);
+ act = thr->callstack + thr->callstack_top - 1;
+ act->curr_pc = thr->catchstack[cat_idx].pc_base + 0; /* +0 = catch */
+ act = NULL;
/*
* If entering a 'catch' block which requires an automatic
@@ -64713,8 +66376,7 @@ DUK_LOCAL void duk__handle_catch_or_finally(duk_hthread *thr,
duk_size_t cat_idx
* which implies the binding is not deletable.
*/
- if (!is_finally &&
DUK_CAT_HAS_CATCH_BINDING_ENABLED(&thr->catchstack[cat_idx])) {
- duk_activation *act;
+ if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(&thr->catchstack[cat_idx])) {
duk_hobject *new_env;
duk_hobject *act_lex_env;
@@ -64747,7 +66409,7 @@ DUK_LOCAL void duk__handle_catch_or_finally(duk_hthread *thr,
duk_size_t cat_idx
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV),
act_lex_env);
- new_env = duk_require_hobject(ctx, -1);
+ new_env = duk_get_hobject(ctx, -1);
DUK_ASSERT(new_env != NULL);
DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *) new_env));
@@ -64759,7 +66421,7 @@ DUK_LOCAL void duk__handle_catch_or_finally(duk_hthread *thr,
duk_size_t cat_idx
DUK_ASSERT(thr->catchstack[cat_idx].h_varname != NULL);
duk_push_hstring(ctx, thr->catchstack[cat_idx].h_varname);
- duk_push_tval(ctx, &thr->heap->lj.value1);
+ duk_push_tval(ctx, thr->valstack + thr->catchstack[cat_idx].idx_base);
duk_xdef_prop(ctx, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */
act = thr->callstack + thr->callstack_top - 1;
@@ -64773,28 +66435,47 @@ DUK_LOCAL void duk__handle_catch_or_finally(duk_hthread *thr,
duk_size_t cat_idx
DUK_DDD(DUK_DDDPRINT("new_env finished: %!iO", (duk_heaphdr *) new_env));
}
- if (is_finally) {
- DUK_CAT_CLEAR_FINALLY_ENABLED(&thr->catchstack[cat_idx]);
- } else {
- DUK_CAT_CLEAR_CATCH_ENABLED(&thr->catchstack[cat_idx]);
- }
+ DUK_CAT_CLEAR_CATCH_ENABLED(&thr->catchstack[cat_idx]);
}
-DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_size_t cat_idx) {
+DUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_size_t cat_idx, duk_tval
*tv_val_unstable, duk_small_uint_t lj_type) {
duk_activation *act;
- /* no callstack changes, no value stack changes */
-
DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(tv_val_unstable != NULL);
+
+ duk__set_catcher_regs(thr, cat_idx, tv_val_unstable, lj_type);
+
+ duk_hthread_catchstack_unwind(thr, cat_idx + 1); /* cat_idx catcher is kept, even for
finally */
+ duk_hthread_callstack_unwind(thr, thr->catchstack[cat_idx].callstack_index + 1);
+
DUK_ASSERT(thr->callstack_top >= 1);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack + thr->callstack_top - 1) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack +
thr->callstack_top - 1)));
+
+ duk__reconfig_valstack_ecma_catcher(thr, thr->callstack_top - 1, cat_idx);
+
+ DUK_ASSERT(thr->callstack_top >= 1);
+ act = thr->callstack + thr->callstack_top - 1;
+ act->curr_pc = thr->catchstack[cat_idx].pc_base + 1; /* +1 = finally */
+ act = NULL;
+
+ DUK_CAT_CLEAR_FINALLY_ENABLED(&thr->catchstack[cat_idx]);
+}
+
+DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_size_t cat_idx, duk_small_uint_t
lj_type) {
+ duk_activation *act;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->callstack_top >= 1);
act = thr->callstack + thr->callstack_top - 1;
DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(act)));
/* +0 = break, +1 = continue */
- act->pc = thr->catchstack[cat_idx].pc_base + (thr->heap->lj.type ==
DUK_LJ_TYPE_CONTINUE ? 1 : 0);
+ act->curr_pc = thr->catchstack[cat_idx].pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE
? 1 : 0);
act = NULL; /* invalidated */
duk_hthread_catchstack_unwind(thr, cat_idx + 1); /* keep label catcher */
@@ -64802,38 +66483,32 @@ DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_size_t
cat_idx) {
/* valstack should not need changes */
#if defined(DUK_USE_ASSERTIONS)
+ DUK_ASSERT(thr->callstack_top >= 1);
act = thr->callstack + thr->callstack_top - 1;
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==
(duk_size_t) ((duk_hcompiledfunction *) DUK_ACT_GET_FUNC(act))->nregs);
#endif
}
-/* Note: called for DUK_LJ_TYPE_YIELD and for DUK_LJ_TYPE_RETURN, when a
- * return terminates a thread and yields to the resumer.
+/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and
+ * when a RETURN opcode terminates a thread and yields to the resumer.
*/
-DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_size_t
act_idx) {
- duk_tval tv_tmp;
+DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_size_t
act_idx, duk_tval *tv_val_unstable) {
duk_tval *tv1;
- /* this may also be called for DUK_LJ_TYPE_RETURN; this is OK as long as
- * lj.value1 is correct.
- */
-
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(resumer != NULL);
+ DUK_ASSERT(tv_val_unstable != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack + act_idx) != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(resumer->callstack +
act_idx))); /* resume caller must be an ecmascript func */
- DUK_DDD(DUK_DDDPRINT("resume idx_retval is %ld", (long)
resumer->callstack[act_idx].idx_retval));
-
tv1 = resumer->valstack + resumer->callstack[act_idx].idx_retval; /* return value
from Duktape.Thread.resume() */
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, &thr->heap->lj.value1);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */
duk_hthread_callstack_unwind(resumer, act_idx + 1); /* unwind to 'resume'
caller */
/* no need to unwind catchstack */
- duk__reconfig_valstack(resumer, act_idx, 1); /* 1 = have retval */
+ duk__reconfig_valstack_ecma_return(resumer, act_idx);
/* caller must change active thread, and set thr->resumer to NULL */
}
@@ -64842,7 +66517,6 @@ DUK_LOCAL
duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
duk_hthread *entry_thread,
duk_size_t entry_callstack_top) {
- duk_tval tv_tmp;
duk_size_t entry_callstack_index;
duk_small_uint_t retval = DUK__LONGJMP_RESTART;
@@ -64855,6 +66529,7 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
/* 'thr' is the current thread, as no-one resumes except us and we
* switch 'thr' in that case.
*/
+ DUK_ASSERT(thr == thr->heap->curr_thread);
/*
* (Re)try handling the longjmp.
@@ -64959,16 +66634,13 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
tv = resumee->valstack + resumee->callstack[act_idx].idx_retval; /* return
value from Duktape.Thread.yield() */
DUK_ASSERT(tv >= resumee->valstack && tv <
resumee->valstack_top);
tv2 = &thr->heap->lj.value1;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv);
- DUK_TVAL_SET_TVAL(tv, tv2);
- DUK_TVAL_INCREF(thr, tv);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2); /* side effects */
duk_hthread_callstack_unwind(resumee, act_idx + 1); /* unwind to 'yield'
caller */
/* no need to unwind catchstack */
- duk__reconfig_valstack(resumee, act_idx, 1); /* 1 = have retval */
+ duk__reconfig_valstack_ecma_return(resumee, act_idx);
resumee->resumer = thr;
resumee->state = DUK_HTHREAD_STATE_RUNNING;
@@ -64992,7 +66664,7 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
/* resumee: [... initial_func undefined(= this) resume_value ] */
- call_flags = DUK_CALL_FLAG_IS_RESUME; /* is resume, not a tailcall */
+ call_flags = DUK_CALL_FLAG_IS_RESUME; /* is resume, not a tail call */
setup_rc = duk_handle_ecma_call_setup(resumee,
1, /* num_stack_args */
@@ -65068,7 +66740,7 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
DUK_DD(DUK_DDPRINT("-> yield an error, converted to a throw in the resumer,
propagate"));
goto check_longjmp;
} else {
- duk__handle_yield(thr, resumer, resumer->callstack_top - 2);
+ duk__handle_yield(thr, resumer, resumer->callstack_top - 2,
&thr->heap->lj.value1);
thr->state = DUK_HTHREAD_STATE_YIELDED;
thr->resumer = NULL;
@@ -65086,201 +66758,6 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
break; /* never here */
}
- case DUK_LJ_TYPE_RETURN: {
- /*
- * Four possible outcomes:
- * * A 'finally' in the same function catches the 'return'.
- * (or)
- * * The return happens at the entry level of the bytecode
- * executor, so return from the executor (in C stack).
- * (or)
- * * There is a calling (Ecmascript) activation in the call
- * stack => return to it.
- * (or)
- * * There is no calling activation, and the thread is
- * terminated. There is always a resumer in this case,
- * which gets the return value similarly to a 'yield'
- * (except that the current thread can no longer be
- * resumed).
- */
-
- duk_tval *tv1;
- duk_hthread *resumer;
- duk_catcher *cat;
- duk_size_t orig_callstack_index;
-
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT(thr->callstack_top >= 1);
- DUK_ASSERT(thr->catchstack != NULL);
-
- /* XXX: does not work if thr->catchstack is NULL */
- /* XXX: does not work if thr->catchstack is allocated but lowest pointer */
-
- cat = thr->catchstack + thr->catchstack_top - 1; /* may be <
thr->catchstack initially */
- DUK_ASSERT(thr->callstack_top > 0); /* ensures callstack_top - 1 >= 0 */
- orig_callstack_index = thr->callstack_top - 1;
-
- while (cat >= thr->catchstack) {
- if (cat->callstack_index != orig_callstack_index) {
- break;
- }
- if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&
- DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- /* 'finally' catches */
- duk__handle_catch_or_finally(thr,
- cat - thr->catchstack,
- 1); /* is_finally */
-
- DUK_DD(DUK_DDPRINT("-> return caught by a finally (in the same function),
restart execution"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
- cat--;
- }
- /* if out of catchstack, cat = thr->catchstack - 1 */
-
- DUK_DD(DUK_DDPRINT("no catcher in catch stack, return to calling activation /
yield"));
-
- /* return to calling activation (if any) */
-
- if (thr == entry_thread &&
- thr->callstack_top == entry_callstack_top) {
- /* return to the bytecode executor caller */
-
- duk_push_tval((duk_context *) thr, &thr->heap->lj.value1);
-
- /* [ ... retval ] */
-
- DUK_DD(DUK_DDPRINT("-> return propagated up to entry level, exit bytecode
executor"));
- retval = DUK__LONGJMP_FINISHED;
- goto wipe_and_return;
- }
-
- if (thr->callstack_top >= 2) {
- /* there is a caller; it MUST be an Ecmascript caller (otherwise it would
- * match entry level check)
- */
-
- DUK_DDD(DUK_DDDPRINT("slow return to Ecmascript caller, idx_retval=%ld,
lj_value1=%!T",
- (long) (thr->callstack + thr->callstack_top -
2)->idx_retval,
- (duk_tval *) &thr->heap->lj.value1));
-
- DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack +
thr->callstack_top - 2))); /* must be ecmascript */
-
- tv1 = thr->valstack + (thr->callstack + thr->callstack_top -
2)->idx_retval;
- DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
- DUK_TVAL_SET_TVAL(tv1, &thr->heap->lj.value1);
- DUK_TVAL_INCREF(thr, tv1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
-
- DUK_DDD(DUK_DDDPRINT("return value at idx_retval=%ld is %!T",
- (long) (thr->callstack + thr->callstack_top -
2)->idx_retval,
- (duk_tval *) (thr->valstack + (thr->callstack +
thr->callstack_top - 2)->idx_retval)));
-
- duk_hthread_catchstack_unwind(thr, (cat - thr->catchstack) + 1); /* leave
'cat' as top catcher (also works if catchstack exhausted) */
- duk_hthread_callstack_unwind(thr, thr->callstack_top - 1);
- duk__reconfig_valstack(thr, thr->callstack_top - 1, 1); /* new top, i.e. callee
*/
-
- DUK_DD(DUK_DDPRINT("-> return not caught, restart execution in
caller"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
-
- DUK_DD(DUK_DDPRINT("no calling activation, thread finishes (similar to
yield)"));
-
- DUK_ASSERT(thr->resumer != NULL);
- DUK_ASSERT(thr->resumer->callstack_top >= 2); /* Ecmascript activation +
Duktape.Thread.resume() activation */
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack +
thr->resumer->callstack_top - 1) != NULL &&
- DUK_HOBJECT_IS_NATIVEFUNCTION(DUK_ACT_GET_FUNC(thr->resumer->callstack
+ thr->resumer->callstack_top - 1)) &&
- ((duk_hnativefunction *) DUK_ACT_GET_FUNC(thr->resumer->callstack +
thr->resumer->callstack_top - 1))->func == duk_bi_thread_resume); /*
Duktape.Thread.resume() */
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack +
thr->resumer->callstack_top - 2) != NULL &&
-
DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->resumer->callstack +
thr->resumer->callstack_top - 2))); /* an Ecmascript function */
- DUK_ASSERT_DISABLE((thr->resumer->callstack + thr->resumer->callstack_top -
2)->idx_retval >= 0); /* unsigned */
- DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
- DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);
-
- resumer = thr->resumer;
-
- duk__handle_yield(thr, resumer, resumer->callstack_top - 2);
-
- duk_hthread_terminate(thr); /* updates thread state, minimizes its allocations */
- DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);
-
- thr->resumer = NULL;
- resumer->state = DUK_HTHREAD_STATE_RUNNING;
- DUK_HEAP_SWITCH_THREAD(thr->heap, resumer);
-#if 0
- thr = resumer; /* not needed */
-#endif
-
- DUK_DD(DUK_DDPRINT("-> return not caught, thread terminated; handle like yield,
restart execution in resumer"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
-
- case DUK_LJ_TYPE_BREAK:
- case DUK_LJ_TYPE_CONTINUE: {
- /*
- * Find a matching label catcher or 'finally' catcher in
- * the same function.
- *
- * A label catcher must always exist and will match unless
- * a 'finally' captures the break/continue first. It is the
- * compiler's responsibility to ensure that labels are used
- * correctly.
- */
-
- duk_catcher *cat;
- duk_size_t orig_callstack_index;
- duk_uint_t lj_label;
-
- cat = thr->catchstack + thr->catchstack_top - 1;
- orig_callstack_index = cat->callstack_index;
-
- DUK_ASSERT(DUK_TVAL_IS_NUMBER(&thr->heap->lj.value1));
- lj_label = (duk_uint_t) DUK_TVAL_GET_NUMBER(&thr->heap->lj.value1);
-
- DUK_DDD(DUK_DDDPRINT("handling break/continue with label=%ld, callstack
index=%ld",
- (long) lj_label, (long) cat->callstack_index));
-
- while (cat >= thr->catchstack) {
- if (cat->callstack_index != orig_callstack_index) {
- break;
- }
- DUK_DDD(DUK_DDDPRINT("considering catcher %ld: type=%ld label=%ld",
- (long) (cat - thr->catchstack),
- (long) DUK_CAT_GET_TYPE(cat),
- (long) DUK_CAT_GET_LABEL(cat)));
-
- if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&
- DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- /* finally catches */
- duk__handle_catch_or_finally(thr,
- cat - thr->catchstack,
- 1); /* is_finally */
-
- DUK_DD(DUK_DDPRINT("-> break/continue caught by a finally (in the same
function), restart execution"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
- if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&
- (duk_uint_t) DUK_CAT_GET_LABEL(cat) == lj_label) {
- /* found label */
- duk__handle_label(thr,
- cat - thr->catchstack);
-
- DUK_DD(DUK_DDPRINT("-> break/continue caught by a label catcher (in the same
function), restart execution"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
- cat--;
- }
-
- /* should never happen, but be robust */
- DUK_D(DUK_DPRINT("break/continue not caught by anything in the current function
(should never happen)"));
- goto convert_to_internal_error;
- }
-
case DUK_LJ_TYPE_THROW: {
/*
* Three possible outcomes:
@@ -65312,12 +66789,12 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
}
if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
- /* try catches */
DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
- duk__handle_catch_or_finally(thr,
- cat - thr->catchstack,
- 0); /* is_finally */
+ duk__handle_catch(thr,
+ cat - thr->catchstack,
+ &thr->heap->lj.value1,
+ DUK_LJ_TYPE_THROW);
DUK_DD(DUK_DDPRINT("-> throw caught by a 'catch' clause, restart
execution"));
retval = DUK__LONGJMP_RESTART;
@@ -65328,9 +66805,10 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));
- duk__handle_catch_or_finally(thr,
- cat - thr->catchstack,
- 1); /* is_finally */
+ duk__handle_finally(thr,
+ cat - thr->catchstack,
+ &thr->heap->lj.value1,
+ DUK_LJ_TYPE_THROW);
DUK_DD(DUK_DDPRINT("-> throw caught by a 'finally' clause, restart
execution"));
retval = DUK__LONGJMP_RESTART;
@@ -65355,7 +66833,7 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
/* Note: MUST NOT wipe_and_return here, as heap->lj must remain intact */
}
- DUK_DD(DUK_DDPRINT("not caught by current thread, yield error to resumer"));
+ DUK_DD(DUK_DDPRINT("-> throw not caught by current thread, yield error to
resumer and recheck longjmp"));
/* not caught by current thread, thread terminates (yield error to resumer);
* note that this may cause a cascade if the resumer terminates with an uncaught
@@ -65387,11 +66865,10 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
goto check_longjmp;
}
- case DUK_LJ_TYPE_NORMAL: {
- DUK_D(DUK_DPRINT("caught DUK_LJ_TYPE_NORMAL, should never happen, treat as
internal error"));
- goto convert_to_internal_error;
- }
-
+ case DUK_LJ_TYPE_BREAK: /* pseudotypes, not used in actual longjmps */
+ case DUK_LJ_TYPE_CONTINUE:
+ case DUK_LJ_TYPE_RETURN:
+ case DUK_LJ_TYPE_NORMAL:
default: {
/* should never happen, but be robust */
DUK_D(DUK_DPRINT("caught unknown longjmp type %ld, treat as internal error",
(long) thr->heap->lj.type));
@@ -65407,83 +66884,249 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;
thr->heap->lj.iserror = 0;
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value1);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
-
- DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value2);
- DUK_TVAL_SET_UNDEFINED_UNUSED(&thr->heap->lj.value2);
- DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1); /* side effects
*/
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2); /* side effects
*/
just_return:
return retval;
convert_to_internal_error:
/* This could also be thrown internally (set the error, goto check_longjmp),
- * but it's better for internal errors to bubble outwards.
+ * but it's better for internal errors to bubble outwards so that we won't
+ * infinite loop in this catchpoint.
*/
DUK_ERROR(thr, DUK_ERR_INTERNAL_ERROR, DUK_STR_INTERNAL_ERROR_EXEC_LONGJMP);
DUK_UNREACHABLE();
return retval;
}
-/* XXX: Disabled for 1.0 release. This needs to handle unwinding for label
- * sites (which are created for explicit labels but also for control statements
- * like for-loops). At that point it's quite close to the "slow return"
handler
- * except for longjmp(). Perhaps all returns could initially be handled as fast
- * returns and only converted to longjmp()s when basic handling won't do?
+/* Handle a BREAK/CONTINUE opcode. Avoid using longjmp() for BREAK/CONTINUE
+ * handling because it has a measurable performance impact in ordinary
+ * environments and an extreme impact in Emscripten (GH-342).
*/
-#if 0
-/* Try a fast return. Return false if fails, so that a slow return can be done
- * instead.
+DUK_LOCAL void duk__handle_break_or_continue(duk_hthread *thr,
+ duk_uint_t label_id,
+ duk_small_uint_t lj_type) {
+ duk_catcher *cat;
+ duk_size_t orig_callstack_index;
+
+ DUK_ASSERT(thr != NULL);
+
+ /*
+ * Find a matching label catcher or 'finally' catcher in
+ * the same function.
+ *
+ * A label catcher must always exist and will match unless
+ * a 'finally' captures the break/continue first. It is the
+ * compiler's responsibility to ensure that labels are used
+ * correctly.
+ */
+
+ /* Note: thr->catchstack_top may be 0, so that cat < thr->catchstack
+ * initially. This is OK and intended.
+ */
+ cat = thr->catchstack + thr->catchstack_top - 1;
+ DUK_ASSERT(thr->callstack_top > 0);
+ orig_callstack_index = thr->callstack_top - 1;
+
+ DUK_DDD(DUK_DDDPRINT("handling break/continue with label=%ld, callstack
index=%ld",
+ (long) label_id, (long) cat->callstack_index));
+
+ while (cat >= thr->catchstack) {
+ if (cat->callstack_index != orig_callstack_index) {
+ break;
+ }
+ DUK_DDD(DUK_DDDPRINT("considering catcher %ld: type=%ld label=%ld",
+ (long) (cat - thr->catchstack),
+ (long) DUK_CAT_GET_TYPE(cat),
+ (long) DUK_CAT_GET_LABEL(cat)));
+
+ if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&
+ DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
+ duk_size_t cat_idx;
+ duk_tval tv_tmp;
+
+ cat_idx = (duk_size_t) (cat - thr->catchstack); /* get before side effects */
+
+#if defined(DUK_USE_FASTINT)
+ DUK_TVAL_SET_FASTINT_U32(&tv_tmp, (duk_uint32_t) label_id);
+#else
+ DUK_TVAL_SET_NUMBER(&tv_tmp, (duk_double_t) label_id);
+#endif
+ duk__handle_finally(thr, cat_idx, &tv_tmp, lj_type);
+
+ DUK_DD(DUK_DDPRINT("-> break/continue